package com.kmzx.one.project.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.kmzx.one.common.constants.Constants;
import com.kmzx.one.common.constants.OrderConstants;
import com.kmzx.one.common.constants.UpMode;
import com.kmzx.one.common.enums.CommonEnums;
import com.kmzx.one.common.enums.TradeTypeEnums;
import com.kmzx.one.common.exceptions.NoSuchObjectException;
import com.kmzx.one.common.exceptions.OrderErrorException;
import com.kmzx.one.common.exceptions.ParameterNullException;
import com.kmzx.one.common.utils.DateTimeUtils;
import com.kmzx.one.common.utils.HttpClientUtil;
import com.kmzx.one.common.utils.StringUtils;
import com.kmzx.one.common.utils.UUIDGenerator;
import com.kmzx.one.project.config.data.WXDataConfig;
import com.kmzx.one.project.config.database.leaf.IDGen;
import com.kmzx.one.project.config.wx.WXTwo;
import com.kmzx.one.project.config.wx.WxPayUtils;
import com.kmzx.one.project.entity.*;
import com.kmzx.one.project.events.PatchProdEvent;
import com.kmzx.one.project.mapper.*;
import com.kmzx.one.project.net.CartParam;
import com.kmzx.one.project.net.OnceParam;
import com.kmzx.one.project.net.OrderParam;
import com.kmzx.one.project.others.common.ExpressArrayInfo;
import com.kmzx.one.project.others.common.FeeData;
import com.kmzx.one.project.others.dso.CartInfo;
import com.kmzx.one.project.others.dso.ProdJoinAWC;
import com.kmzx.one.project.others.dso.ProdJoinAttributeWithCategory;
import com.kmzx.one.project.others.dso.ProdJoinDiscount;
import com.kmzx.one.project.others.dso.ProductExtraInfo;
import com.kmzx.one.project.others.dso.ProductSelfJoinSKU;
import com.kmzx.one.project.others.dso.UserOrderDso;
import com.kmzx.one.project.others.dso.UserRankMoney;
import com.kmzx.one.project.others.dto.*;
import com.kmzx.one.project.others.vos.ExpressInfos;
import com.kmzx.one.project.service.UserOrderService;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

@Service
public class UserOrderServiceImpl implements UserOrderService {

    @Value("${aliyun.market.appcode}")
    private String appCode;
    @Value("${aliyun.express.address}")
    private String expressAddress;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserOrderMapper userOrderMapper;

    @Autowired
    private UserRankMapper userRankMapper;

    @Autowired
    private FastUpMapper fastUpMapper;

    @Autowired
    private UserGrowthDetailMapper userGrowthDetailMapper;

    @Autowired
    private UserPayMapper userPayMapper;

    @Autowired
    private OrderBillMoneyMapper orderBillMoneyMapper;

    @Autowired
    private UserAddressMapper userAddressMapper;

    @Autowired
    private UserCartMapper userCartMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private WarehouseMapper warehouseMapper;

    @Autowired
    CustomerMapper customerMapper;

    @Autowired
    SimpleMapper simpleMapper;

    @Autowired
    WxUserMapper wxUserMapper;

    @Autowired
    private UserProfitMapper userProfitMapper;

    @Autowired
    private UserExchangeRateMapper userExchangeRateMapper;

    @Autowired
    private RedisTemplate<String, Object> stringObjectRedisTemplate;

    @Autowired
    ApplicationContext applicationContext;
    @Autowired
    WXDataConfig wxDataConfig;

    @Autowired
    WxPayMapper wxPayMapper;

    @Autowired
    ProductSelfMapper productSelfMapper;

    @Autowired
    IDGen idGen;

    @Autowired
    private ProdBaseMapper prodBaseMapper;

    private Lock midLock = new ReentrantLock(true);

    @Override
    public List<UserOrderOutInfo> findUserAllOrder(String userId, Integer pageNum, Integer pageSize, Integer kinds) throws Exception {
        pageNum = (pageNum - 1) * pageSize;
        long version41 = 1585708507701l;
        List<UserOrderDso> subOrders;
        if (kinds != null)
            kinds = kinds - 1;

        if (kinds == 0 || kinds == 1 || kinds == 2) {
            subOrders = userOrderMapper.selectUserOrderAllPager(userId, pageNum, pageSize, kinds);
        } else if (kinds == 3) {
            subOrders = userOrderMapper.selectUserOrderAllPager(userId, pageNum, pageSize, 4);
        } else {
            subOrders = userOrderMapper.selectUserOrderAllPager2(userId, pageNum, pageSize);
        }
        ArrayList<UserOrderOutInfo> details = new ArrayList<>();
        if (subOrders.size() != 0) {
            List<Business> businesses = simpleMapper.selectBusinessNameAll();
            List<TradeWarehouse> warehouseAll = simpleMapper.selectTradeWarehouseAll();
            for (UserOrderDso subOrder : subOrders) {
                String allInfo = subOrder.getAllInfo();
                // 商品名 | 货号 | 属性
                String[] info = allInfo.split("\\|");
                subOrder.setProdName(info[0]);
                subOrder.setProdAttr(info[2]);
                BigDecimal tariffFee = subOrder.getTariffFee();
                BigDecimal expressFee = subOrder.getExpressFee();
                if (tariffFee == null) {
                    subOrder.setTariffFee(BigDecimal.ZERO);
                }
                if (expressFee == null) {
                    subOrder.setExpressFee(BigDecimal.ZERO);
                }

                BigDecimal prodDiscount = subOrder.getProdDiscount();
                if (prodDiscount == null) {
                    subOrder.setProdDiscount(BigDecimal.ONE);
                }

                BigDecimal currPrice = subOrder.getCurrPrice();
                if (currPrice == null) {
                    subOrder.setCurrPrice(subOrder.getProdPrice().multiply(subOrder.getProdDiscount()));
                    subOrder.setCurrentPrice(subOrder.getProdPrice().multiply(subOrder.getProdDiscount()));
                }
                BigDecimal account = subOrder.getAccount();
                if (account == null) {
                    subOrder.setAccount(BigDecimal.ZERO);
                }
                BigDecimal repository = subOrder.getRepository();
                if (repository == null) {
                    subOrder.setRepository(BigDecimal.ZERO);
                }
//                -------------------------deleted
                if (subOrder.getTradeType() == null) {
                    subOrder.setTradeType(2);
                }

                Integer kinds1 = subOrder.getKinds();
                if (kinds1 == null) {
                    subOrder.setKinds(OrderConstants.NORMAL_ORDER);
                }
            }
            Map<String, List<UserOrderDso>> map = subOrders.stream().collect(Collectors.groupingBy(UserOrderDso::getOrderId));

            Set<String> set = map.keySet();
            for (String s : set) {
                List<UserOrderDso> userOrderDtos = map.get(s);

                Integer orderStates = userOrderDtos.get(0).getStates();
                for (UserOrderDso dto : userOrderDtos) {
                    String businessCode = dto.getBusinessCode();
                    if (businessCode == null) {
                        dto.setBusinessCode("001");
                    }
                }


                Map<String, List<UserOrderDso>> businessMap = userOrderDtos.stream().collect(Collectors.groupingBy(UserOrderDso::getBusinessCode));
                if ((businessMap != null && businessMap.size() >= 2) && orderStates != 0 && orderStates != 5) {
                    Set<String> businessSet = businessMap.keySet();
                    ArrayList<UserOrderOutInfo> bSetList = new ArrayList<>();
                    for (String bSet : businessSet) {
                        List<UserOrderDso> dsos = businessMap.get(bSet);
                        UserOrderOutInfo outInfo = new UserOrderOutInfo();
                        outInfo.setOrderId(dsos.get(0).getOrderId() + "_" + dsos.get(0).getBusinessCode());

                        long count = dsos.stream().map(lt -> lt.getProdNum()).reduce((a, b) -> a + b).get();
                        outInfo.setCounts(count);
                        outInfo.setDetail(dsos);
                        outInfo.setTime(dsos.get(0).getTimeStr());
                        outInfo.setTimeStamp(dsos.get(0).getCreateTime().getTime());
                        BigDecimal billSub = dsos.stream().map(lv -> lv.getBillMoney()).reduce((a, b) -> a.add(b)).get();
                        outInfo.setBillMoney(billSub);
                        outInfo.setStates(orderStates);
                        BigDecimal billEnd = dsos.stream().map(lv -> lv.getEndMoney()).reduce((a, b) -> a.add(b)).get();
                        outInfo.setEndMoney(billEnd);
                        outInfo.setTotalMoney(billEnd);
                        outInfo.setTradeType(dsos.get(0).getTradeType());
                        outInfo.setOrderDiscount(dsos.get(0).getOrderDiscount());

                        outInfo.setTariffFee(dsos.stream().map(ll -> ll.getTariffFee()).reduce((c, d) -> c.add(d)).get());
                        outInfo.setExFee(dsos.stream().map(ll -> ll.getExpressFee()).reduce((c, d) -> c.add(d)).get());

                        Integer tradeType = dsos.get(0).getTradeType();
                        if (tradeType != null) {
                            if (tradeType == 1) {
                                outInfo.setTariffFee(BigDecimal.ZERO);
                                outInfo.setExFee(dsos.get(0).getGateExpressFee());
                            } else if (tradeType == 0) {
                                String businessCode = userOrderDtos.get(0).getBusinessCode();
                                for (Business business : businesses) {
                                    if (business.getBusinessCode().equals(businessCode)) {
                                        outInfo.setGroupName(business.getDisplayName());
                                        break;
                                    }
                                }
                            } else if (tradeType == 2) {
                                String tradeNum = dsos.get(0).getTradeNum();
                                if (tradeNum != null) {
                                    for (TradeWarehouse tw : warehouseAll) {
                                        if (tw.getTradeNum().equals(tradeNum)) {
                                            outInfo.setGroupName(tw.getTradeWarehouseName());
                                            break;
                                        }
                                    }
                                } else {
                                    String timeStr = userOrderDtos.get(0).getTimeStr();
                                    outInfo.setGroupName(timeStr);
                                }
                            }
                        }

                        outInfo.setChannel(dsos.get(0).getChannel());

                        BigDecimal gateExpressFee = dsos.get(0).getGateExpressFee();
                        if (gateExpressFee == null) {
                            gateExpressFee = BigDecimal.ZERO;
                        }
//                BigDecimal ecoMoney = gateExpressFee.add(billSub).subtract(billEnd);
                        BigDecimal ecoMoney = BigDecimal.ZERO.add(billSub).subtract(billEnd);
//                        .add(outInfo.getExFee()).add(outInfo.getTariffFee());
                        outInfo.setEcoMoney(ecoMoney);

                        BigDecimal orderDiscount = outInfo.getOrderDiscount();
                        if (outInfo.getTimeStamp() < version41) {
                            if (outInfo.getEndMoney().compareTo(BigDecimal.ZERO) == 0) {
                                outInfo.setRepository(outInfo.getTotalMoney());
                            }
                        }
                        if (orderDiscount != null) {
                            if (orderDiscount.compareTo(BigDecimal.ONE) < 0) {
                                outInfo.setOrderDiscount(orderDiscount.multiply(BigDecimal.TEN));
                            }
                            if (orderDiscount.compareTo(BigDecimal.ONE) == 0) {
                                outInfo.setOrderDiscount(BigDecimal.TEN);
                            }
                        } else {
                            BigDecimal discounts = billEnd.divide(billSub, 2, BigDecimal.ROUND_HALF_UP);
                            if (discounts != null) {

                                if (discounts.compareTo(BigDecimal.ONE) == 0) {
                                    outInfo.setOrderDiscount(BigDecimal.TEN);
                                } else {
                                    // 包含邮费的
                                    outInfo.setOrderDiscount(BigDecimal.TEN);
                                }

                                if (discounts.compareTo(BigDecimal.ONE) <= 0) {
                                    outInfo.setOrderDiscount(discounts.multiply(BigDecimal.TEN));
                                }
                            }
                        }

                        BigDecimal account = outInfo.getAccount();
                        BigDecimal repository = outInfo.getRepository();
                        if (account == null) {
                            outInfo.setAccount(BigDecimal.ZERO);
                        }
                        if (repository == null) {
                            outInfo.setRepository(BigDecimal.ZERO);
                        }
                        BigDecimal sumAccount = dsos.get(0).getAccount();
                        outInfo.setAccount(sumAccount);
                        BigDecimal sumRepo = dsos.get(0).getRepository();
                        outInfo.setRepository(sumRepo);
                        //--------------------------deleted-----------------------------
                        if (outInfo.getTradeType() == 2) {
                            outInfo.setExFee(BigDecimal.ZERO);
                        }
                        outInfo.setKinds(dsos.get(0).getKinds());
                        bSetList.add(outInfo);
                    }
                    details.addAll(bSetList);
                } else {
                    UserOrderOutInfo outInfo = new UserOrderOutInfo();
                    outInfo.setOrderId(s);
                    BigDecimal zero = BigDecimal.ZERO;
                    userOrderDtos.forEach(st -> zero.add(st.getProdPrice().multiply(BigDecimal.valueOf(st.getProdNum()))));

                    long count = userOrderDtos.stream().map(lt -> lt.getProdNum()).reduce((a, b) -> a + b).get();
                    outInfo.setCounts(count);
                    outInfo.setDetail(userOrderDtos);
                    outInfo.setTime(userOrderDtos.get(0).getTimeStr());
                    outInfo.setTimeStamp(userOrderDtos.get(0).getCreateTime().getTime());
                    BigDecimal billSub = userOrderDtos.stream().map(lv -> lv.getBillMoney()).reduce((a, b) -> a.add(b)).get();
                    outInfo.setBillMoney(billSub);
                    outInfo.setStates(orderStates);
                    BigDecimal billEnd = userOrderDtos.stream().map(lv -> lv.getEndMoney()).reduce((a, b) -> a.add(b)).get();
                    outInfo.setEndMoney(userOrderDtos.get(0).getUpEndMoney());
                    outInfo.setTotalMoney(billEnd);
                    outInfo.setTradeType(userOrderDtos.get(0).getTradeType());
                    outInfo.setOrderDiscount(userOrderDtos.get(0).getOrderDiscount());

                    outInfo.setTariffFee(userOrderDtos.stream().map(ll -> ll.getTariffFee()).reduce((c, d) -> c.add(d)).get());
                    outInfo.setExFee(userOrderDtos.stream().map(ll -> ll.getExpressFee()).reduce((c, d) -> c.add(d)).get());

                    Integer tradeType = userOrderDtos.get(0).getTradeType();
                    if (tradeType != null) {
                        if (tradeType == 1) {
                            outInfo.setTariffFee(BigDecimal.ZERO);
                            outInfo.setExFee(userOrderDtos.get(0).getGateExpressFee());
                            outInfo.setGroupName("KM 自营");
                        } else if (tradeType == 0) {
//                            String businessCode = userOrderDtos.get(0).getBusinessCode();
//                            if (businessCode != null) {
//                                for (Business business : businesses) {
//                                    if (business.getBusinessCode().equals(businessCode)) {
//                                        outInfo.setGroupName(business.getDisplayName());
//                                    }
//                                }
//                            } else {
//                                String timeStr = userOrderDtos.get(0).getTimeStr();
//                                outInfo.setGroupName(timeStr);
//                            }
                            outInfo.setGroupName("KM 自营");
                        } else if (tradeType == 2) {
                            String tradeNum = userOrderDtos.get(0).getTradeNum();
                            if (tradeNum != null) {
                                for (TradeWarehouse tw : warehouseAll) {
                                    if (tw.getTradeNum().equals(tradeNum)) {
                                        outInfo.setGroupName(tw.getTradeWarehouseName());
                                        break;
                                    }
                                }
                            } else {
                                outInfo.setGroupName("KM 自营");
                            }
                        }
                    }

                    outInfo.setChannel(userOrderDtos.get(0).getChannel());

                    BigDecimal gateExpressFee = userOrderDtos.get(0).getGateExpressFee();
                    if (gateExpressFee == null) {
                        gateExpressFee = BigDecimal.ZERO;
                    }
//                BigDecimal ecoMoney = gateExpressFee.add(billSub).subtract(billEnd);
                    BigDecimal ecoMoney = BigDecimal.ZERO.add(billSub).subtract(billEnd);
//                        .add(outInfo.getExFee()).add(outInfo.getTariffFee());
                    outInfo.setEcoMoney(ecoMoney);

                    BigDecimal orderDiscount = outInfo.getOrderDiscount();
                    if (outInfo.getTimeStamp() < version41) {
                        if (outInfo.getEndMoney().compareTo(BigDecimal.ZERO) == 0) {
                            outInfo.setRepository(outInfo.getTotalMoney());
                        }
                    }
                    if (orderDiscount != null) {
                        if (orderDiscount.compareTo(BigDecimal.ONE) < 0) {
                            outInfo.setOrderDiscount(orderDiscount.multiply(BigDecimal.TEN));
                        }
                        if (orderDiscount.compareTo(BigDecimal.ONE) == 0) {
                            outInfo.setOrderDiscount(BigDecimal.TEN);
                        }
                    } else {
                        BigDecimal discounts = billEnd.divide(billSub, 2, BigDecimal.ROUND_HALF_UP);
                        if (discounts != null) {

                            if (discounts.compareTo(BigDecimal.ONE) == 0) {
                                outInfo.setOrderDiscount(BigDecimal.TEN);
                            } else {
                                // 包含邮费的
                                outInfo.setOrderDiscount(BigDecimal.TEN);
                            }

                            if (discounts.compareTo(BigDecimal.ONE) <= 0) {
                                outInfo.setOrderDiscount(discounts.multiply(BigDecimal.TEN));
                            }
                        }
                    }

                    BigDecimal account = outInfo.getAccount();
                    BigDecimal repository = outInfo.getRepository();
                    if (account == null) {
                        outInfo.setAccount(BigDecimal.ZERO);
                    }
                    if (repository == null) {
                        outInfo.setRepository(BigDecimal.ZERO);
                    }
                    BigDecimal sumAccount = userOrderDtos.get(0).getAccount();
                    outInfo.setAccount(sumAccount);
                    BigDecimal sumRepo = userOrderDtos.get(0).getRepository();
                    outInfo.setRepository(sumRepo);
                    //--------------------------deleted-----------------------------
                    if (outInfo.getTradeType() == 2) {
                        outInfo.setExFee(BigDecimal.ZERO);
                    }
                    outInfo.setKinds(userOrderDtos.get(0).getKinds());
                    details.add(outInfo);
                }

            }

            details.sort(Comparator.comparing(UserOrderOutInfo::getTimeStamp).reversed());
        }
        return details;
    }

    @Override
    public UserOrderMoreInfo findUserOrderDetail(String orderId) throws Exception {
        boolean flag = false;
        String businessCode = null;
        if (orderId.contains("_")) {
            String[] complexOrderId = orderId.split("_");
            String originOrderId = complexOrderId[0];
            businessCode = complexOrderId[1];
            orderId = originOrderId;
            flag = true;
        }
        UserOrderMoreInfo moreInfo = userOrderMapper.selectUserOrderDetail(orderId);

        if (moreInfo != null) {
            List<UserOrderDso> subDetail = userOrderMapper.selectUserOrderSubDetail(orderId);
            if (flag) {
                subDetail = userOrderMapper.selectUserOrderSubDetailBusiness(orderId, businessCode);
            }
            for (UserOrderDso dso : subDetail) {
                String allInfo = dso.getAllInfo();
                String[] threeInfo = allInfo.split("\\|");
                String attr = threeInfo[2];
                String name = threeInfo[0];
                BigDecimal currPrice = dso.getCurrPrice();
                if (currPrice == null) {
                    dso.setCurrPrice(dso.getProdPrice());
                }
                dso.setProdName(name);
                dso.setProdAttr(attr);
            }
            long count = subDetail.stream().map(lt -> lt.getProdNum()).reduce((a, b) -> a + b).get();
            moreInfo.setCounts(count);
            moreInfo.setTotalMoney(subDetail.stream().map(mp -> mp.getEndMoney()).reduce((a, b) -> a.add(b)).get());
            moreInfo.setDetail(subDetail);
            moreInfo.setExpressCompany(subDetail.get(0).getExpressCompany());
            moreInfo.setExpressCode(subDetail.get(0).getExpressCode());
            Integer kinds = moreInfo.getKinds();
            if (kinds == null) {
                moreInfo.setKinds(OrderConstants.NORMAL_ORDER);
            }

            subDetail.forEach(lt -> lt.setKinds(moreInfo.getKinds()));

            BigDecimal orderDiscount = moreInfo.getOrderDiscount();

            if (orderDiscount != null) {
                if (orderDiscount.compareTo(BigDecimal.ONE) == 0) {
                    moreInfo.setOrderDiscount(BigDecimal.TEN);
                }
                if (orderDiscount.compareTo(BigDecimal.ONE) < 0) {
                    moreInfo.setOrderDiscount(orderDiscount.multiply(BigDecimal.TEN));
                }

            } else {
                BigDecimal totalMoney = moreInfo.getTotalMoney();
                BigDecimal billMoney = moreInfo.getBillMoney();
                BigDecimal discounts = totalMoney.divide(billMoney, 2, BigDecimal.ROUND_HALF_UP);
                if (discounts != null) {
                    if (discounts.compareTo(BigDecimal.ONE) < 0) {
                        moreInfo.setOrderDiscount(discounts.multiply(BigDecimal.TEN));
                    }
                    if (discounts.compareTo(BigDecimal.ONE) == 0) {
                        moreInfo.setOrderDiscount(BigDecimal.TEN);
                    }
                }

            }
            if (moreInfo.getExFee() == null) {
                moreInfo.setExFee(BigDecimal.ZERO);
            }
            if (moreInfo.getTariffFee() == null) {
                moreInfo.setTariffFee(BigDecimal.ZERO);
            }

            Integer tradeType = moreInfo.getTradeType();
            if (tradeType != null) {
                if (tradeType == 1) {
                    moreInfo.setExFee(moreInfo.getGateExpressFee());
                    moreInfo.setTariffFee(BigDecimal.ZERO);
                }
                if (tradeType == 2) {
                    String repoName = prodBaseMapper.selectRepoName(moreInfo.getTradeNum());
                    moreInfo.setRepoName(repoName);
                }
            }
            if (flag) {
                BigDecimal billSub = subDetail.stream().map(lv -> lv.getBillMoney()).reduce((a, b) -> a.add(b)).get();
                BigDecimal endSub = subDetail.stream().map(mp -> mp.getEndMoney()).reduce((a, b) -> a.add(b)).get();
                moreInfo.setBillMoney(billSub);
                moreInfo.setEndMoney(endSub);
                BigDecimal ecoMoney = billSub.subtract(moreInfo.getTotalMoney());
                moreInfo.setEcoMoney(ecoMoney);
            } else {
                BigDecimal ecoMoney = moreInfo.getBillMoney().subtract(moreInfo.getTotalMoney());
//                    .add(moreInfo.getExFee()).add(moreInfo.getTariffFee());
                moreInfo.setEcoMoney(ecoMoney);

            }
            return moreInfo;
        } else {
            throw new ParameterNullException("数据为空");
        }
    }

    @Override
    @Transactional
    public Integer doCancelOrder(String userId, String orderId, String reason) throws Exception {
        UserOrder order = userOrderMapper.selectById(orderId);
        Integer states = order.getStates();
        UserRankInfo rankInfo = userRankMapper.selectUserRankTabs(userId);
        stringObjectRedisTemplate.delete(Constants.rank_up_prefix + ":" + userId + ":" + rankInfo.getRankNum());
        if (states == 0) {
            Date date = new Date();
            order.setStates(5);
            order.setUpdateTime(date);
            int c = userOrderMapper.updateByIdSelective(order);
            int batchUpdateSubOrder = userOrderMapper.batchUpdateSubOrder(orderId, 5, date);


            BigDecimal repoMoney = order.getPayMoney();
            BigDecimal profitMoney = order.getProfitMoney();

            if (repoMoney != null && repoMoney.compareTo(BigDecimal.ZERO) > 0) {
                FreightInfo freight = customerMapper.selectUserFreight(order.getUserId());
                String tempId = freight.getTempId();
                UserPay userPay = new UserPay();
                userPay.setMoney(freight.getMoney().add(repoMoney));
                userPay.setUpdateTime(date);
                userPay.setId(tempId);
                userPayMapper.updateByIdSelective(userPay);

            }

            if (profitMoney != null && profitMoney.compareTo(BigDecimal.ZERO) > 0) {
                UserProfitInfo userProfitInfo = customerMapper.selectUserProfit(order.getUserId());
                UserProfit userProfit = new UserProfit();
                userProfit.setId(userProfitInfo.getTemps());
                userProfit.setUpdateTime(date);
                userProfit.setProfitMoney(userProfitInfo.getCanPay().add(profitMoney));
                userProfitMapper.updateByIdSelective(userProfit);
            }


            List<WarehouseDetail> warehouseDetails = warehouseMapper.selectWarehouseInfoByOrderId(orderId, 0);

            List<Warehouse> warehouseList = new ArrayList<>();
            if (warehouseDetails != null && warehouseDetails.size() > 0) {
//                for (WarehouseDetail warehouseDetail : warehouseDetails) {
//                    // 取消了
//                    Integer order_down_number = warehouseDetail.getProductNumber();
//                    warehouseDetail.setUpdateTime(date);
//                    warehouseDetail.setStates(1);
//                    Warehouse warehouse = warehouseMapper.selectWarehouseByBatchSkuId(warehouseDetail.getAttributeWithCategoryId(), warehouseDetail.getWarehouseBatch());
//                    if (warehouse != null) {
//                        Integer old_number = warehouse.getNowNumber();
//                        warehouse.setUpdateTime(date);
//                        warehouse.setNowNumber(old_number + order_down_number);
//                        warehouseList.add(warehouse);
//                    }
//                }
//                // 将库存明细表回撤状态
//                warehouseMapper.batchUpdateWarehouseDetail(warehouseDetails);
//                // 将库存表回填
//                warehouseMapper.batchUpdateWarehouse(warehouseList);


                Map<String, List<WarehouseDetail>> collect = warehouseDetails.stream().collect(Collectors.groupingBy(WarehouseDetail::getAttributeWithCategoryId));

                for (Map.Entry<String, List<WarehouseDetail>> entry : collect.entrySet()) {
                    List<WarehouseDetail> value = entry.getValue();
                    value.sort(Comparator.comparing(WarehouseDetail::getWarehouseBatch).reversed());
/*

                String attributeWithCategoryId = value.get(0).getAttributeWithCategoryId();
                Warehouse wh = warehouseMapper.selectWarehouseBySkuId(attributeWithCategoryId);
                if(wh.getIsBack()==1){

                }else {

                }
*/

                    for (int i = 0; i < value.size(); i++) {
                        WarehouseDetail warehouseDetail = value.get(i);
                        Integer order_down_number = warehouseDetail.getProductNumber();
                        warehouseDetail.setStates(1);
                        warehouseDetail.setUpdateTime(date);

                        Warehouse warehouse = warehouseMapper.selectWarehouseById(warehouseDetail.getWarehouseId());
                        if (warehouse != null) {
                            Integer isBack = warehouse.getIsBack();
                            if (isBack == 1) {
                                List<ProductSelf> selfList = productSelfMapper.selectByProdIdHas(warehouseDetail.getProductId());

                                for (ProductSelf self : selfList) {
                                    ProductSelfJoinSKU selfJoinSKU = productSelfMapper.selectProductSelfJoinSKUOne(self.getProductSubsId());
                                    Integer isMulti = self.getIsMulti();
                                    if (isMulti == 0) {
                                        selfJoinSKU = productSelfMapper.selectProdSelfJoinSKUSingle(self.getSkuId());
                                    }

                                    selfJoinSKU.setNeedNum(self.getNeedNum());
                                    List<Warehouse> whList = warehouseMapper.selectWarehouseByProdIdSKU(selfJoinSKU.getProductSubsId(), selfJoinSKU.getSkuId(), warehouse.getTradeNum());
                                    for (int j = 0; j < whList.size(); j++) {
                                        Warehouse whl = whList.get(j);
                                        Integer behalf = whl.getBehalf();
                                        Integer nowNumber = whl.getNowNumber();

                                        Integer warehouseNumber = whl.getWarehouseNumber();
                                        int num = order_down_number * selfJoinSKU.getProdNum() * selfJoinSKU.getNeedNum();
                                        if (warehouseNumber.equals(nowNumber)) {
                                            continue;
                                        } else {
                                            if (warehouseNumber >= nowNumber + num) {
                                                if (behalf != null && behalf == 0) {
                                                    whl.setNowNumber(0);
                                                } else {
                                                    whl.setNowNumber(nowNumber + num);
                                                }
                                                whl.setUpdateTime(date);
                                                WarehouseDetail whd1 = new WarehouseDetail();
                                                whd1.setId(UUIDGenerator.generate())
                                                        .setCreateTime(date).setUpdateTime(date)
                                                        .setSubsCodes(warehouseDetail.getSubsCodes())
                                                        .setStates(6)
                                                        .setOrdersId(warehouseDetail.getOrdersId())
                                                        .setOrderCodes(warehouseDetail.getOrderCodes());
                                                whd1.setWarehouseBatch(whl.getWarehouseBatch())
                                                        .setProductMoney(null).setNowCost(whl.getNowCost())
                                                        .setProductNumber(num)
                                                        .setProductId(whl.getProductId())
                                                        .setProfiles(whl.getProfiles())
                                                        .setProductName(whl.getProductName())
                                                        .setAttributeWithCategoryId(whl.getAttributeWithCategoryId())
                                                        .setAttributeWithCategoryName(whl.getAttributeWithCategoryName());


                                                warehouseMapper.updateWarehouseByIdSel(whl);
                                                warehouseMapper.insertWarehouseDetail(whd1);
                                                break;
                                            } else {
                                                if (behalf != null && behalf == 0) {
                                                    whl.setNowNumber(0);
                                                } else {
                                                    whl.setNowNumber(warehouseNumber - nowNumber);
                                                }
                                                whl.setUpdateTime(date);
                                                WarehouseDetail whd1 = new WarehouseDetail();
                                                whd1.setId(UUIDGenerator.generate())
                                                        .setSubsCodes(warehouseDetail.getSubsCodes())
                                                        .setCreateTime(date).setUpdateTime(date)
                                                        .setStates(6)
                                                        .setOrdersId(warehouseDetail.getOrdersId())
                                                        .setOrderCodes(warehouseDetail.getOrderCodes());
                                                whd1.setWarehouseBatch(whl.getWarehouseBatch())
                                                        .setProductMoney(null).setNowCost(whl.getNowCost())
                                                        .setProductNumber(warehouseNumber - nowNumber)
                                                        .setProductId(whl.getProductId())
                                                        .setProfiles(whl.getProfiles())
                                                        .setProductName(whl.getProductName())
                                                        .setAttributeWithCategoryId(whl.getAttributeWithCategoryId())
                                                        .setAttributeWithCategoryName(whl.getAttributeWithCategoryName());


                                                warehouseMapper.updateWarehouseByIdSel(whl);
                                                warehouseMapper.insertWarehouseDetail(whd1);

                                                num = num - (warehouseNumber - nowNumber);
                                            }
                                        }
                                    }
                                }
                            } else {
                                Integer behalf = warehouseDetail.getBehalf();
                                if (behalf != null && behalf == 0) {
                                    warehouse.setNowNumber(0);
                                } else {
                                    Integer old_number = warehouse.getNowNumber();
                                    warehouse.setNowNumber(old_number + order_down_number);
                                }
                                warehouse.setUpdateTime(date);
                                warehouseList.add(warehouse);
                                // 将库存明细表回撤状态
                                warehouseMapper.batchUpdateWarehouseDetail(warehouseDetails);
                                // 将库存表回填
                                warehouseMapper.batchUpdateWarehouse(warehouseList);
                            }

                        }
                    }
                }

            }

            return c + batchUpdateSubOrder;
        } else {
            throw new ParameterNullException("该订单状态异常,取消失败!");
        }
    }

    @Override
    public Map<String, Object> findOrderExpressInfo(String orderId) throws Exception {
        Map<String, String> info = new HashMap<>();
        if (orderId.contains("_")) {
            String[] complexOrderId = orderId.split("_");
            String originOrderId = complexOrderId[0];
            info = userOrderMapper.selectSubOrderExpressInfoBusiness(complexOrderId[0], complexOrderId[1]);
        } else {
            info = userOrderMapper.selectSubOrderExpressInfo(orderId);
        }

        if (!CollectionUtils.isEmpty(info)) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("expressCodes", info.get("expressCodes"));
            map.put("expressName", info.get("expressName"));
            String icon = customerMapper.findExpressIcon(info.get("express_number"));
            if (icon != null) {
                map.put("expressIcon", icon);
            } else {
                map.put("expressIcon", customerMapper.findExpressIcon("shunfeng"));
            }
            return map;
        } else {
            throw new NoSuchObjectException(CommonEnums.NO_Express_Info.getCode(), CommonEnums.NO_Express_Info.getMsg());
        }
    }


    @Override
    public Map<String, Object> findOrderExpressDetail(String orderId) throws Exception {
        Map<String, String> info = new HashMap<>();
        if (orderId.contains("_")) {
            String[] complexOrderId = orderId.split("_");
            String originOrderId = complexOrderId[0];
            info = userOrderMapper.selectSubOrderExpressInfoBusiness(complexOrderId[0], complexOrderId[1]);
        } else {
            info = userOrderMapper.selectSubOrderExpressInfo(orderId);
        }
//        Map<String, String> info = userOrderMapper.selectSubOrderExpressInfo(orderId);
        if (!CollectionUtils.isEmpty(info)) {
            ExpressInfos express = findNewExpressInfo(orderId, info.get("subId"), info.get("express_number"), info.get("subsCodes"), info.get("expressCodes"));
            HashMap<String, Object> map = new HashMap<>();
            map.put("content", express.getCnt());
            return map;
        } else {
            throw new NoSuchObjectException(CommonEnums.NO_Express_Info.getCode(), CommonEnums.NO_Express_Info.getMsg());
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer doExchangeOrder(String orderId, int what, String reason, String[] pics) throws Exception {
        UserOrderSubs subs = userOrderMapper.selectSubsOrderById(orderId);
        if (subs == null) {
            throw new ParameterNullException("暂无该订单");
        }

        Integer states = subs.getStates();
        if (states != 3) {
            throw new ParameterNullException("该订单状态异常");
        }
        subs.setId(orderId);
        subs.setReason1(reason);
        subs.setUpdateTime(new Date());
        subs.setTime1(subs.getUpdateTime());
        int length = pics.length;
        if (length > 3) {
            throw new ParameterNullException("图片数量已超限!");
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            if (StringUtils.isNotEmpty(pics[i]) && i != 2) {
                sb.append(pics[i]).append(",");
            } else if (StringUtils.isNotEmpty(pics[i])) {
                sb.append(pics[i]);
            }
        }
        String picsUrls = sb.toString();
        subs.setApplyPic(picsUrls);
        //  0,换货,1,退货
        String ordersId = subs.getOrdersId();
        UserOrder userOrder = new UserOrder();
        userOrder.setId(ordersId);
        if (what == 0) {
            subs.setStates(9);
            userOrder.setStates(9);
        }
//        else {
//            LockProfitEvent lockProfitEvent = new LockProfitEvent(subs.getUserId(), "退货");
//            lockProfitEvent.setMoney(subs.getSubBill());
//            lockProfitEvent.setOrderId(subs.getOrdersId());
//            lockProfitEvent.setSubOrderId(subs.getId());
//            applicationContext.publishEvent(lockProfitEvent);
//            subs.setStates(6);
//            userOrder.setStates(6);
//        }
        int main = userOrderMapper.updateByIdSelective(userOrder);
        int sub = userOrderMapper.updateSubsByIdSelective(subs);
        if (main > 0 && sub > 0) {
            return 1;
        } else {
            throw new OrderErrorException(502, "订单换货异常");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer doConfirmOrder(String orderId) throws Exception {
        UserOrder order = userOrderMapper.selectById(orderId);
        Date date = new Date();
        order.setStates(3);
        order.setUpdateTime(date);
        order.setRemark("用户确认");
        int main = userOrderMapper.updateByIdSelective(order);
        int sub = userOrderMapper.batchUpdateSubOrder(orderId, 3, date);
        if (main > 0 && sub > 0) {
            return 1;
        } else {
            throw new OrderErrorException(502, "订单换货异常");
        }
    }

    @Override
    public UserOrderFinalInfo doGenOrder(OrderParam orderParam) throws Exception {
        int i = orderParam.checkWhich();
        if (i == 0) {
            throw new ParameterNullException("参数为空,不支持交易");
        }
        if (i == 1) {

            UserOrderFinalInfo cart = null;
            midLock.lock();
            try {
                cart = dealWithCart(orderParam.getCart());
            } catch (Exception e) {
                e.printStackTrace();
                String message = e.getMessage();
                logger.error("异常了" + message);
                if (e instanceof NoSuchObjectException) {
                    throw new ParameterNullException(message);
                } else if(e instanceof ParameterNullException){
                    throw new ParameterNullException(message);
                } else {
                    throw new ParameterNullException("交易处理中.请稍后重试");
                }
            } finally {
                midLock.unlock();
            }
            return cart;
        }
        if (i == 2) {

            UserOrderFinalInfo once = null;
            midLock.lock();
            try {
                once = dealWithOnce(orderParam.getOnce());
            } catch (Exception e) {
                e.printStackTrace();
                String message = e.getMessage();
                logger.error("异常了" + message);
                if (e instanceof NoSuchObjectException) {
                    throw new ParameterNullException(message);
                } else if(e instanceof ParameterNullException){
                    throw new ParameterNullException(message);
                } else {
                    throw new ParameterNullException("交易处理中.请稍后重试");
                }
            } finally {
                midLock.unlock();
            }
            return once;
        }
        return null;
    }

    @Autowired
    WxPayUtils wxPayUtils;

    @Override
    public Object doPayOrder(String orderId, String userId) throws Exception {
        WxUser wxUser = wxUserMapper.selectById(userId);
        String openId = wxUser.getOpenId();
        UserOrder order = userOrderMapper.selectById(orderId);
        Integer states = order.getStates();
        if (states == 0) {
            List<UserGrowthDetail> details = simpleMapper.selectUserGrowthDetail(userId, orderId, UpMode.SelfBuy);
            if (!CollectionUtils.isEmpty(details)) {
                UserGrowthDetail detail = details.get(0);
                Double growthValue = detail.getGrowthValue();
                BigDecimal end = BigDecimal.valueOf(growthValue);
                BigDecimal endMoney = order.getEndMoney();
                // 够了
                if (end.compareTo(endMoney) >= 0) {

                } else {
                    // 0待支付 1待发货 2 待收货 3已完成 4 支付失败 5 已取消 6待退款 7已退款 8 退款失败 9 待审核 10 审核成功 11 审核失败
                    WxPayMpOrderResult orderResult = wxPayUtils.payOrder(UUIDGenerator.generate(), openId, order.getEndMoney().subtract(end), order.getOrdersCodes(), "快美甄选,支付:" + order.getOrdersCodes(), orderId);
//            orderResult.get
                    logger.info("订单支付返回数据:{}", orderResult);
                    return orderResult;
                }
            } else {
                // 0待支付 1待发货 2 待收货 3已完成 4 支付失败 5 已取消 6待退款 7已退款 8 退款失败 9 待审核 10 审核成功 11 审核失败
                WxPayMpOrderResult orderResult = wxPayUtils.payOrder(UUIDGenerator.generate(), openId, order.getEndMoney(), order.getOrdersCodes(), "快美甄选,支付:" + order.getOrdersCodes(), orderId);
//            orderResult.get
                logger.info("订单支付返回数据:{}", orderResult);
                return orderResult;
            }
            return null;
        } else {
            if (states == 1) {
                throw new ParameterNullException("该订单已支付,待发货!");
            }
            if (states == 2) {
                throw new ParameterNullException("该订单已发货,待收货!");
            }
            if (states == 3) {
                throw new ParameterNullException("该订单已完成,请勿多付款!");
            }
            if (states == 4) {
                throw new ParameterNullException("该订单支付失败,请勿重试!");
            }
            if (states == 5) {
                throw new ParameterNullException("该订单已取消,请勿重试!");
            } else {
                throw new ParameterNullException("该订单异常,请勿重试!");
            }
        }
    }

    @Override
    public UserOrder findUserOrderById(String orderNo) throws Exception {
        UserOrder order = userOrderMapper.selectById(orderNo);
        if (order != null) {
            return order;
        } else {
            throw new NoSuchObjectException(401, "订单不存在");
        }
    }

    @Override
    public UserOrder findUserOrderByCodes(String orderNo) throws Exception {
        UserOrder order = userOrderMapper.selectUserOrderByOrderCodes(orderNo);
        if (order != null) {
            return order;
        } else {
            throw new NoSuchObjectException(401, "订单不存在");
        }
    }

    @Override
    public Integer doDelOrder(String orderId, String userId) throws Exception {
        UserOrder order = userOrderMapper.selectById(orderId);
        if (order != null) {
            Date date = new Date();
            order.setUpdateTime(date);
            order.setDeleted(1);
            int update = userOrderMapper.updateByIdSelective(order);
            return update;
        } else {
            throw new NoSuchObjectException(401, "订单不存在");
        }
    }

    @Override
    public OrderBackInfo findSubOrderBack(String orderId) throws Exception {
        UserOrderSubs subs = userOrderMapper.selectSubsOrderById(orderId);
        if (subs != null) {
            String applyPic = subs.getApplyPic();
            String[] allPics = applyPic.split(",");

            OrderBackInfo info = new OrderBackInfo();
            info.setOrderId(orderId)
                    .setPics(Arrays.asList(allPics))
                    .setReason(subs.getReason1())
                    .setReply(subs.getReason2())
                    .setStates(subs.getStates())
                    .setTimes(DateTimeUtils.formatLocalDate(subs.getTime1()));
            return info;
        } else {
            throw new NoSuchObjectException(401, "订单不存在");
        }
    }

    @Override
    public UserOrderFinalInfo doGenFastOrder(OrderParam orderParam) {
        midLock.lock();
        UserOrderFinalInfo userOrderFinalInfo = null;
        try {
            userOrderFinalInfo = middleDoOrder(orderParam);
        } catch (Exception e) {
            e.printStackTrace();
            String message = e.getMessage();
            logger.error("异常了" + message);
            if (e instanceof NoSuchObjectException) {
                throw new ParameterNullException(message);
            } else if(e instanceof ParameterNullException){
                throw new ParameterNullException(message);
            } else {
                throw new ParameterNullException("交易处理中.请稍后重试");
            }
        } finally {
            midLock.unlock();
        }
        return userOrderFinalInfo;
    }

    //    public UserOrderFinalInfo doGenFastOrder(OrderParam orderParam) throws Exception {
    public UserOrderFinalInfo middleDoOrder(OrderParam orderParam) throws Exception {
        OnceParam once = orderParam.getOnce();
        String userId = once.getUserId();
        String skuId = once.getSkuId();
        String addressId = once.getAddressId();
        String prodId = once.getProdId();
        String tradeNum = once.getTradeNum();

        int profit = once.getUse();
        int account = once.getAccount();
        // 库存量
        long buyNum = once.getNum();


        WxUser wxUser = wxUserMapper.selectById(userId);
        if (wxUser == null) {
            throw new NoSuchObjectException("该用户不存在");
        }

        boolean isGod = false;
        List<String> specUsers = customerMapper.findSpecificUser();
        if (specUsers != null && specUsers.size() > 0 && specUsers.contains(userId)) {
            isGod = true;
        }

        UserRankInfo rankInfo = userRankMapper.selectUserRankTabs(userId);
        Integer ranks = fastUpMapper.selectSkuRank("", skuId);
        if (ranks == null) {
            UserOrderFinalInfo info = dealWithOnce(once);
            return info;
//            throw new ParameterNullException("商品异常!");
        } else {
            if (rankInfo.getRankNum() > ranks) {
                if (!CollectionUtils.isEmpty(specUsers) && (userId != null && userId != "")) {
                    if (!specUsers.contains(userId)) {
                        throw new ParameterNullException("您的等级不符合,下单失败!");
//                        specific = true;
//                        UserOrderFinalInfo userOrderFinalInfo = dealWithOnce(once);
//                        return userOrderFinalInfo;
                    }
                }
            }
        }

        Product product = productMapper.selectProdById(prodId);

        if (product == null || (product != null && product.getStates() == 1)) {
            throw new ParameterNullException("该商品已下架");
        }
        if (product.getIsBehalf() != null && product.getIsBehalf() == 0) {
            logger.info("代发商品无库存");
        } else {
            List<Warehouse> warehouseList = warehouseMapper.selectWarehouseInfo(skuId, tradeNum);
            if (CollectionUtils.isEmpty(warehouseList)) {
                throw new ParameterNullException("该商品不存在");
            }
            int totalStore = warehouseList.stream().mapToInt(s -> s.getNowNumber()).sum();
            if (totalStore == 0) {
                throw new NoSuchObjectException(402, "暂无库存 o(╥﹏╥)o");
            }
            Integer prodNum = warehouseList.get(0).getProdNum();
            if (prodNum != null && prodNum != 0) {
                if (totalStore < buyNum * prodNum) {
                    throw new NoSuchObjectException(402, "数量超过库存啦");
                }
            } else {
                if (totalStore < buyNum) {
                    throw new NoSuchObjectException(402, "数量超过库存啦");
                }
            }
        }

        int fastGrade = productMapper.selectFastGradeBySkuId(skuId);

        Date date = new Date();
        String orderId = idGen.getIdDefault() + "";
        String orderCodes = UUIDGenerator.generateOrderNo("FG");
        // 子订单
        List<UserOrderSubs> subOrders = new ArrayList<>();

        HashMap<String, String[]> two = new HashMap<>();
        HashMap<String, String> three = new HashMap<>();
        HashMap<String, String> four = new HashMap<>();


        // 用户地址
        UserAddress address = userAddressMapper.selectById(addressId);
        String code = address.getCode();
        List<String> codes = Arrays.asList("540000", "650000", "710000", "810000", "820000", "900000");
        if (code != null && !codes.contains(code)) {
            code = "E";
        }
        if (code == null || "".equals(code)) {
            code = "E";
        }
        address.setCode(code);
        String realName = "";
        String idCard = "";
        String phone = "";

        // 校验订单的实名信息
        if (product.getInOrOut() == 2) {
            List<UserVerifyInfo> verifyInfos = customerMapper.selectUserVerifyInfo(userId);
            if (verifyInfos != null && verifyInfos.size() > 0) {
                realName = verifyInfos.get(0).getUsername();
                idCard = verifyInfos.get(0).getIdCard();
                phone = verifyInfos.get(0).getPhone();
            } else {
                throw new NoSuchObjectException(402, "您的实名信息与微信不一致,请核验后重试!");
            }
        }

        // 用户等级信息
        UserRankMoney userRank = userRankMapper.selectUserRankAndMoney(userId);
        if (userRank != null) {
            userRank.setTradeNum(tradeNum);
        }
        Object o = stringRedisTemplate.opsForValue().get(Constants.rank_up_prefix + ":" + userId + ":" + userRank.getRankNum());
        if (o != null) {
            throw new NoSuchObjectException(402, "您还有待支付的直升订单,请处理后继续!");
        }

        // 额外费
        List<ProductExtraInfo> extraFees = userCartMapper.selectProdExtraInfo();
        // 海外包邮
        List<FeeData> data = productMapper.selectProductFeeData2();
        int seaOrIn = 0;
        //  总订单金额
        BigDecimal totalBill = BigDecimal.ZERO;
        // 最终金额
        BigDecimal truthPayMoney = BigDecimal.ZERO;
        // 所有的关税
        BigDecimal totalGateFee = BigDecimal.ZERO;
        UserOrderSubs subOrder = orderMultiProcess(1, userId, isGod, idCard, skuId, (int) buyNum, date, orderId, orderCodes, userRank, totalBill
                , totalGateFee, extraFees, code, realName);
        totalBill = subOrder.getTempBill();
        BigDecimal tempDiscount = subOrder.getTempDiscount();
        totalGateFee = subOrder.getTempGateFee();
        subOrders.add(subOrder);

        // 订单的realMoney
        BigDecimal orderRealMoney = subOrders.stream().map(UserOrderSubs::getRealMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal expressFree = subOrders.get(0).getExpressFree();
        int toUseExpress = subOrders.get(0).getToUseExpress();
        seaOrIn = subOrder.getInOrOut();
        for (UserOrderSubs sub : subOrders) {
            BigDecimal realExFee = expressFree.multiply(sub.getSubBill()).divide(totalBill, 2, BigDecimal.ROUND_HALF_UP);
            sub.setExpressFree(realExFee);
            // 需要交 运费
            if (toUseExpress == 0) {
                BigDecimal subEnd = sub.getSubEnd();
                sub.setSubEnd(subEnd.add(realExFee));
            }
            if (sub.getToUseTariff() == 0) {
                BigDecimal subEnd = sub.getSubEnd();
                sub.setSubEnd(subEnd.add(sub.getTariffFree()));
            }
        }

        truthPayMoney = subOrders.stream().map(UserOrderSubs::getSubEnd).reduce(BigDecimal.ZERO, BigDecimal::add);


        UserOrder order = new UserOrder();
        order.setCreateTime(date).setUpdateTime(date).setId(orderId);
        order.setAddressId(addressId).setUserId(userId);
        order.setDeleted(0).setStates(0).setUserDiscount(1.0);
        order.setProfitMoney(BigDecimal.ZERO).setPayMoney(BigDecimal.ZERO);
        order.setOrdersCodes(orderCodes).setPhone(phone);
        order.setBillMoney(totalBill).setEndMoney(truthPayMoney);
        order.setTariffFree(totalGateFee).setTradeType(seaOrIn);
        order.setRealMoney(orderRealMoney).setOrderDiscount(tempDiscount.doubleValue());
        order.setOrderChannel(wxUser.getIdentityType());
        order.setSendMoney(subOrder.getSendMoney());
        if (tradeNum != null && !"".equals(tradeNum)) {
            order.setTradeNum(tradeNum);
        } else {
            if (seaOrIn == 0) {
                order.setTradeNum("001");
            } else if (seaOrIn == 2) {
                order.setTradeNum("002");
            }
        }

        order.setRemark(once.getSay());
        order.setUsername(address.getUserName())
                .setMobile(address.getMobile())
                .setProvince(address.getProvince())
                .setCity(address.getCity())
                .setTown(address.getTown())
                .setOthers(address.getOthers());
        if (seaOrIn == 1) {
            order.setGateExpressFee(expressFree);
            order.setPushStates(-1);
        } else {
            if (seaOrIn == 0) {
                order.setPushStates(-1);
            } else {
                order.setPushStates(0);
            }
            order.setGateExpressFee(BigDecimal.ZERO);
        }
        order.setYunfei(expressFree);
        if (userRank != null) {
            order.setUserDiscount(userRank.getUserDiscount().doubleValue());
        }
        order.setProdNum((int) buyNum);
        order.setFastOrder(OrderConstants.FAST_ORDER).setFastGrade(fastGrade);

        UserOrderFinalInfo uof = new UserOrderFinalInfo();
        uof.setOrderId(orderId).setOrderNo(order.getOrdersCodes())
                .setOrderMoney(truthPayMoney).setNeedPay(0).setNeedMoney(truthPayMoney);
        String cre = DateTimeUtils.formatLocalDate(order.getCreateTime());
        uof.setCreateTime(cre).setChannel(wxUser.getIdentityType()).setUserId(userId);


        // 我的账户
        UserProfit userProfitL1 = new UserProfit();

        if (account == 1 && product.getInOrOut() == 0 && !isGod) {

            // 勾选余额付款
            UserProfitInfo userProfitInfo = customerMapper.selectUserProfit(userId);
            if (userProfitInfo != null) {
                BigDecimal canPay = userProfitInfo.getCanPay();
                // 充足,账户钱够用
                if (truthPayMoney.compareTo(canPay) <= 0) {
                    // 已经使用了货仓余额
                    userProfitL1.setId(userProfitInfo.getTemps());
                    userProfitL1.setProfitMoney(canPay.subtract(truthPayMoney));
                    userProfitL1.setUpdateTime(date);


                    order.setEndMoney(BigDecimal.ZERO);
                    order.setStates(1);
                    subOrder.setStates(1);


                    uof.setNeedPay(1);
                    uof.setNeedMoney(BigDecimal.ZERO);
                    uof.setOrderMoney(BigDecimal.ZERO);


                    StringBuilder stringBuilder = new StringBuilder(Constants.rewardOrderPrefix);
                    stringBuilder.append(order.getUserId() + "_" + subOrder.getInOrOut()).append(",")
                            .append(truthPayMoney).append(",")
                            .append(order.getId()).append(",")
                            .append(date.getTime()).append(",")
                            .append("profit");


                    UserGrowthDetail growInfo = new UserGrowthDetail();
                    growInfo.setCreateTime(date);
                    growInfo.setId(UUIDGenerator.generate());
                    growInfo.setGrowthValue(truthPayMoney.doubleValue());
                    growInfo.setUpMode(UpMode.SelfBuy);
                    growInfo.setOrdersId(orderId);
                    order.setFinishTime(date);
                    growInfo.setUserId(userId);
                    growInfo.setFromUserId(userId);
                    order.setProfitMoney(truthPayMoney);
                    order.setPayMoney(BigDecimal.ZERO);
                    userGrowthDetailMapper.insert(growInfo);
                    userProfitMapper.updateByIdSelective(userProfitL1);

                    // 订单倒计时,15秒后计算 等级收益
                    stringObjectRedisTemplate.opsForValue().set(stringBuilder.toString(), stringBuilder.toString(), 15, TimeUnit.SECONDS);
                    saveOrderAndSubsOfOnce(order, subOrder);
                    boolean NingBoNormal = subOrder.getTradeNum().equals("005");
                    warehouseMapper.successWarehouseDetail(2, date, order.getId());
                    if (NingBoNormal) {
                        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
                        opsForValue.set(Constants.ning_bo_normal + order.getId() + "_" + order.getId(), order.getId(), 10, TimeUnit.SECONDS);
                        // todo  更新库存表
                        stringRedisTemplate.delete(Constants.lifestyleOrderPrefix + order.getId());
                    }

                    return uof;
                }
            }
        }
        uof.setNeedMoney(truthPayMoney);
        uof.setOrderMoney(truthPayMoney);
        // 任何都没勾选
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        opsForValue.set(Constants.lifestyleOrderPrefix + orderId, orderId, 12, TimeUnit.HOURS);
        opsForValue.set(Constants.rank_up_prefix + ":" + userId + ":" + userRank.getRankNum(), userId);
        saveOrderAndSubsOfOnce(order, subOrder);
        return uof;
    }

    @Override
    public WikiH5PayResponse wikiH5Pay(String orderId, String userId, String clientIP) throws Exception {
        WikiH5PayResponse response = new WikiH5PayResponse();
        response.setReturn_code("FAIL");
        response.setReturn_msg("");
        response.setPayHtml(wxDataConfig.getH5WapUrl());
        response.setChannel(1);
        response.setOrderId(orderId);
        UserOrder order = userOrderMapper.selectById(orderId);
        //待支付
        if (null != order && order.getStates() == 0) {
            Integer tradeType = order.getFastOrder();
            if (tradeType == TradeTypeEnums.Sea_Trade.getCode()) {
                int i = userOrderMapper.countFastUserOrderNum(userId, TradeTypeEnums.Sea_Trade.getCode(), order.getFastGrade());
                if (i > 0) {
                    throw new ParameterNullException("您已经购买过直升商品了!");
                }
            }

            WikiPayRequest payRequest = new WikiPayRequest();
            payRequest.setAppid(wxDataConfig.getAppId());
            payRequest.setMch_id(wxDataConfig.getMerchantNum());
            payRequest.setNonce_str(UUIDGenerator.generator());
            payRequest.setBody("快美甄选-化妆品销售 订单号:" + order.getOrdersCodes());
            payRequest.setOut_trade_no(order.getOrdersCodes());
            //金额
            BigDecimal payMoney = order.getEndMoney();
            DecimalFormat df = new DecimalFormat("#");
            String money = df.format(payMoney.multiply(new BigDecimal(100)));
            payRequest.setTotal_fee(Integer.parseInt(money));
            payRequest.setSpbill_create_ip(clientIP);
            payRequest.setNotify_url(wxDataConfig.getH5CallbackUrl() + "/" + orderId);
            String s1 = "'h5_info':{'type':'Wap','wap_url':'" + wxDataConfig.getH5WapUrl() + "','wap_name': '" + wxDataConfig.getH5WapName() + "'}";

            payRequest.setScene_info(s1);

            //签名
            SortedMap<String, Object> map = new TreeMap();
            map.put("appid", payRequest.getAppid());
            map.put("mch_id", payRequest.getMch_id());
            map.put("nonce_str", payRequest.getNonce_str());
            map.put("body", payRequest.getBody());
            map.put("out_trade_no", payRequest.getOut_trade_no());
            map.put("total_fee", payRequest.getTotal_fee());
            map.put("spbill_create_ip", payRequest.getSpbill_create_ip());
            map.put("notify_url", payRequest.getNotify_url());
            map.put("trade_type", payRequest.getTrade_type());
            map.put("scene_info", s1);
            StringBuilder strb = new StringBuilder();
            Set<String> keySet = map.keySet();
            for (String key : keySet) {
                Object value = map.get(key);
                strb.append(key).append("=").append(value);
                strb.append("&");
            }

            strb.append("key=").append(wxDataConfig.getMerchantKey());
            String sign = DigestUtils.md5Hex(strb.toString()).toUpperCase();
            payRequest.setSign(sign);

            String xmlReq = payRequest.toXML();
            String req = xmlReq.replace("&apos;", "'");
            Date date = new Date();
            WxPayOrder wxPayOrder = new WxPayOrder();
            wxPayOrder.setId(payRequest.getNonce_str()).setBankType(null)
                    .setCreateTime(date).setUpdateTime(date)
                    .setSuccess(1).setNonce(payRequest.getNonce_str())
                    .setTotalFee(payRequest.getTotal_fee())
                    .setUserOrdersId(orderId)
                    .setWxReq(xmlReq);
            wxPayMapper.insertWxPayOrder(wxPayOrder);
            String res = HttpClientUtil.postXmlBody(wxDataConfig.getPayUrl(), req);
            if (!StringUtils.isEmpty(res)) {
                WikiPayResponse wikiPayResponse = (WikiPayResponse) WikiPayResponse.fromXML(res);
                if (null != wikiPayResponse) {
                    if ("SUCCESS".equals(wikiPayResponse.getReturn_code()) && "SUCCESS".equals(wikiPayResponse.getResult_code())) {
                        response.setReturn_code("SUCCESS");
                        response.setPrepay_id(wikiPayResponse.getPrepay_id());
                        response.setMweb_url(wikiPayResponse.getMweb_url());
                        response.setOrderMoney(order.getEndMoney());
                        response.setPayHtml(wxDataConfig.getH5WapUrl());
                        response.setWxUrl(wikiPayResponse.getMweb_url());


                        System.out.println("wikiPayResponse.getMweb_url() = " + wikiPayResponse.getMweb_url());

                        String[] split = wikiPayResponse.getMweb_url().split("\\?");
                        response.setDoPay(split[1]);

                    } else {
                        response.setReturn_msg(wikiPayResponse.getReturn_msg());
                    }
                }
            }

        }
        return response;
    }

    @Override
    public Object doWXMiniPay(String orderId, String userId, String clientIP) throws Exception {
        WxUser wxUser = wxUserMapper.selectById(userId);
        String openId = wxUser.getOpenId();
        UserOrder order = userOrderMapper.selectById(orderId);
        Integer states = order.getStates();
        if (states == 0) {
            Integer tradeType = order.getFastOrder();
            if (tradeType == TradeTypeEnums.Sea_Trade.getCode()) {
                int i = userOrderMapper.countFastUserOrderNum(userId, TradeTypeEnums.Sea_Trade.getCode(), order.getFastGrade());
                if (i > 0) {
                    throw new ParameterNullException("您已经购买过直升商品了!");
                }
            }
            // 0待支付 1待发货 2 待收货 3已完成 4 支付失败 5 已取消 6待退款 7已退款 8 退款失败 9 待审核 10 审核成功 11 审核失败

//            WxPayMpOrderResult orderResult = wxPayUtils.payOrder(UUIDGenerator.generate(), openId, order.getEndMoney(), order.getOrdersCodes(), "快美甄选,支付:" + order.getOrdersCodes(), orderId);
//            orderResult.get
//            order.getEndMoney()
            String payOrderId = UUIDGenerator.generate();
            WXTwo payOrderIP = wxPayUtils.payOrderIP(payOrderId, openId, order.getEndMoney(), order.getOrdersCodes(), "快美甄选-化妆品销售 订单号:" + order.getOrdersCodes(), orderId, clientIP);
            if (payOrderIP != null) {
                WxPayUnifiedOrderRequest req = payOrderIP.getReq();
                Date date = new Date();
                String s = req.toXML();
                WxPayOrder wxPayOrder = new WxPayOrder();
                wxPayOrder.setId(payOrderId).setBankType(null)
                        .setCreateTime(date).setUpdateTime(date)
                        .setSuccess(1).setNonce(payOrderId)
                        .setTotalFee(req.getTotalFee())
                        .setUserOrdersId(orderId)
                        .setWxReq(s);
                wxPayMapper.insertWxPayOrder(wxPayOrder);
                WxPayMpOrderResult result = payOrderIP.getResult();
                logger.info("订单支付返回数据:{}", result);
                return result;
            } else {
                throw new NoSuchObjectException("下单失败");
            }
//            return null;
        } else {
            if (states == 1) {
                throw new ParameterNullException("该订单已支付,待发货!");
            }
            if (states == 2) {
                throw new ParameterNullException("该订单已发货,待收货!");
            }
            if (states == 3) {
                throw new ParameterNullException("该订单已完成,请勿多付款!");
            }
            if (states == 4) {
                throw new ParameterNullException("该订单支付失败,请勿重试!");
            }
            if (states == 5) {
                throw new ParameterNullException("该订单已取消,请勿重试!");
            } else {
                throw new ParameterNullException("该订单异常,请勿重试!");
            }
        }
    }

    @Autowired
    private UserCartMapper cartMapper;

    public UserOrderFinalInfo dealWithCart(CartParam cartParam) {
        String userId = cartParam.getUserId();
        List<String> cartIds = cartParam.getIds();
        String addressId = cartParam.getAddressId();
        int profit = cartParam.getUse();
        int account = cartParam.getAccount();

        WxUser wxUser = wxUserMapper.selectById(userId);
        if (wxUser == null) {
            throw new NoSuchObjectException("该用户不存在");
        }

        boolean isGod = false;
        List<String> specUsers = customerMapper.findSpecificUser();
        if (specUsers != null && specUsers.size() > 0 && specUsers.contains(userId)) {
            isGod = true;
        }

        if (CollectionUtils.isEmpty(cartIds)) {
            throw new ParameterNullException("购物车商品不存在");
        }

        cartIds = cartIds.stream().distinct().collect(Collectors.toList());


        List<CartInfo> cartIf = userCartMapper.collectUserCartInfo(cartIds);
        if (CollectionUtils.isEmpty(cartIf)) {
            throw new ParameterNullException("购物车中物品不存在");
        } // 商品总数
        long prodtotal = 0l;
        prodtotal = cartIf.stream().mapToLong(st -> st.getBuyCount()).sum();
        if (prodtotal == 0) {
            throw new NoSuchObjectException(402, "一丁点儿数量都没 o(╥﹏╥)o");
        }
        String tradeNum = cartIf.get(0).getTradeNum();
        Integer inOrOut = cartIf.get(0).getInOrOut();

        // 海关限制
        List<UserCartLimitInfo> limitInfos = cartMapper.selectUserCartLimitInfo();
        boolean hasLimit = false;
        UserCartLimitInfo userCartLimitInfo = new UserCartLimitInfo();
        if (limitInfos != null && limitInfos.size() > 0) {

            userCartLimitInfo = limitInfos.stream().filter(ll -> ll.getTradeNum().equals(tradeNum) && ll.getProdLimits() > 0).findFirst().get();
            if (userCartLimitInfo != null) {
                hasLimit = true;
                if (inOrOut == 2 && (userCartLimitInfo.getProdLimits() < prodtotal)) {
                    throw new ParameterNullException("^_^ 亲, 单笔订单超过可购买数量");
                }
            }
        }
        for (CartInfo ci : cartIf) {
            Integer prodStates = ci.getProdStates();
            if (prodStates == 1) {
                throw new ParameterNullException("商品:" + ci.getProdName() + " 已下架");
            }
            Integer skuStates = ci.getSkuStates();
            if (skuStates == 1) {
                throw new ParameterNullException("商品:" + ci.getProdName() + " 已下架");
            }

            Integer buyCount = ci.getBuyCount();
            if (buyCount == 0) {
                throw new ParameterNullException("商品:" + ci.getProdName() + " 扣减数量异常,下单失败");
            }
            Integer behalf = ci.getBehalf();
            if (behalf != null && behalf == 0) {
                logger.info("代发商品,暂无库存....,购物车");
            } else {

                Integer prodNum = ci.getProdNum();
                if (prodNum != null && prodNum != 0) {
                    if (ci.getWhCount() < buyCount * prodNum) {
                        throw new ParameterNullException("商品:" + ci.getProdName() + " 库存不足");
//                        throw new NoSuchObjectException(402, "数量超过库存啦");
                    }
                } else {
                    if (ci.getWhCount() < buyCount) {
                        throw new ParameterNullException("商品:" + ci.getProdName() + " 库存不足");
//                        throw new NoSuchObjectException(402, "数量超过库存啦");
                    }
                }
//                if (buyCount > ci.getWhCount()) {
//                    throw new ParameterNullException("商品:" + ci.getProdName() + " 库存不足");
//                }
            }
            if (hasLimit) {
                if (inOrOut == 2 && (userCartLimitInfo.getProdLimits() < buyCount)) {
                    throw new ParameterNullException("^_^ 亲, 单笔订单超过可购买数量");
                }
            }
        }

        Date date = new Date();
        String orderId = UUIDGenerator.generate();
        String orderCodes = UUIDGenerator.generateOrderNo("PG");
        // 子订单
        List<UserOrderSubs> subOrders = new ArrayList<>();

        // 用户地址
        UserAddress address = userAddressMapper.selectById(addressId);
        String code = address.getCode();
        List<String> codes = Arrays.asList("540000", "650000", "710000", "810000", "820000", "900000");
        if (code != null && !codes.contains(code)) {
            code = "E";
        }
        if (code == null || "".equals(code)) {
            code = "E";
        }
        address.setCode(code);


        String realName = "";
        String idCard = "";
        String phone = "";

        // 校验订单的实名信息
        if (inOrOut == 2) {
            List<UserVerifyInfo> verifyInfos = customerMapper.selectUserVerifyInfo(userId);
            if (verifyInfos != null && verifyInfos.size() > 0) {
                realName = verifyInfos.get(0).getUsername();
                idCard = verifyInfos.get(0).getIdCard();
                phone = verifyInfos.get(0).getPhone();
            } else {
                throw new NoSuchObjectException(402, "您的实名信息与微信不一致,请核验后重试!");
            }
        }

        // 用户等级信息
        UserRankMoney userRank = userRankMapper.selectUserRankAndMoney(userId);


        // 额外费
        List<ProductExtraInfo> extraFees = userCartMapper.selectProdExtraInfo();
        // 海外包邮
        List<FeeData> data = productMapper.selectProductFeeData2();

        //  总订单金额
        BigDecimal totalBill = BigDecimal.ZERO;
        // 最终金额
        BigDecimal truthPayMoney = BigDecimal.ZERO;
        // 所有的关税
        BigDecimal totalGateFee = BigDecimal.ZERO;
        BigDecimal tempDiscount = BigDecimal.ONE;
        for (int i = 0; i < cartIf.size(); i++) {
            CartInfo info = cartIf.get(i);
            String skuId = info.getSkuId();
            if (userRank != null) {
                userRank.setTradeNum(info.getTradeNum());
            }
            UserOrderSubs subOrder = orderMultiProcess(3, userId, isGod, idCard, skuId, info.getBuyCount(), date, orderId, orderCodes, userRank, totalBill
                    , totalGateFee, extraFees, code, realName);

            totalBill = subOrder.getTempBill();
            totalGateFee = subOrder.getTempGateFee();
            tempDiscount = subOrder.getTempDiscount();
            subOrders.add(subOrder);
        }

        if (hasLimit) {
            int sum = subOrders.stream().mapToInt(t -> t.getTotalProdNum()).sum();
            if (inOrOut == 2 && (userCartLimitInfo.getProdLimits() < sum)) {
                throw new ParameterNullException("^_^ 亲, 单笔订单超过可购买数量");
            }
        }

        // 订单的realMoney
        BigDecimal orderRealMoney = subOrders.stream().map(UserOrderSubs::getRealMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal sendMoney = subOrders.stream().map(UserOrderSubs::getSendMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal expressFree = subOrders.get(0).getExpressFree();
        int toUseExpress = subOrders.get(0).getToUseExpress();
        int seaOrIn = subOrders.get(0).getInOrOut();

        BigDecimal endExFee = BigDecimal.ZERO;
        for (int i = 0; i < subOrders.size(); i++) {
            UserOrderSubs sub = subOrders.get(i);
            BigDecimal realExFee = BigDecimal.ZERO;
            if (i != subOrders.size() - 1) {
                realExFee = expressFree.multiply(sub.getSubBill()).divide(totalBill, 2, BigDecimal.ROUND_HALF_UP);
                endExFee = endExFee.add(realExFee);
            } else {
                realExFee = expressFree.subtract(endExFee).setScale(2, BigDecimal.ROUND_HALF_UP);
            }
            sub.setExpressFree(realExFee);
            // 需要交 运费
            if (toUseExpress == 0) {
                BigDecimal subEnd = sub.getSubEnd();
                sub.setSubEnd(subEnd.add(realExFee));
            }
            if (sub.getToUseTariff() == 0) {
                BigDecimal subEnd = sub.getSubEnd();
                sub.setSubEnd(subEnd.add(sub.getTariffFree()));
            }
        }

        truthPayMoney = subOrders.stream().map(UserOrderSubs::getSubEnd).reduce(BigDecimal.ZERO, BigDecimal::add);


        UserOrder order = new UserOrder();
        order.setCreateTime(date).setUpdateTime(date).setId(orderId);
        order.setAddressId(addressId).setUserId(userId);
        order.setDeleted(0).setStates(0).setUserDiscount(1.0);
        order.setProfitMoney(BigDecimal.ZERO).setPayMoney(BigDecimal.ZERO);
        order.setOrdersCodes(orderCodes).setPhone(phone);
        order.setBillMoney(totalBill).setEndMoney(truthPayMoney);
        order.setTariffFree(totalGateFee);
        order.setTradeType(seaOrIn).setOrderDiscount(tempDiscount.doubleValue());
        order.setOrderChannel(wxUser.getIdentityType());
        order.setSendMoney(sendMoney);

        // 下单备注
        order.setRemark(cartParam.getSay());
        order.setUsername(address.getUserName())
                .setMobile(address.getMobile())
                .setProvince(address.getProvince())
                .setCity(address.getCity())
                .setTown(address.getTown())
                .setOthers(address.getOthers());

        if (seaOrIn == 1) {
            order.setGateExpressFee(expressFree);
            order.setPushStates(-1);
        } else {
            if (seaOrIn == 0) {
                order.setPushStates(-1);
            } else {
                order.setPushStates(0);
            }
            order.setGateExpressFee(BigDecimal.ZERO);
        }
        if (tradeNum != null && !"".equals(tradeNum)) {
            order.setTradeNum(tradeNum);
        } else {
            if (seaOrIn == 0) {
                order.setTradeNum("001");
            } else if (seaOrIn == 2) {
                order.setTradeNum("002");
            }
        }
        order.setYunfei(expressFree);
        if (userRank != null) {
            order.setUserDiscount(userRank.getUserDiscount().doubleValue());
        }
        order.setProdNum((int) prodtotal);
        order.setFastOrder(OrderConstants.NORMAL_ORDER);
        order.setRealMoney(orderRealMoney);

        UserOrderFinalInfo uof = new UserOrderFinalInfo();
        uof.setOrderId(orderId).setOrderNo(order.getOrdersCodes()).setNeedMoney(truthPayMoney)
                .setOrderMoney(truthPayMoney).setNeedPay(0);
        String cre = DateTimeUtils.formatLocalDate(order.getCreateTime());
        uof.setCreateTime(cre).setChannel(wxUser.getIdentityType()).setUserId(userId);


        // 我的账户
        UserProfit userProfitL1 = new UserProfit();
        if (account == 1 && seaOrIn == 0 && !isGod) {
            // 勾选余额付款
            UserProfitInfo userProfitInfo = customerMapper.selectUserProfit(userId);
            if (userProfitInfo != null) {
                BigDecimal canPay = userProfitInfo.getCanPay();
                // 充足,账户钱够用
                if (truthPayMoney.compareTo(canPay) <= 0) {
                    // 已经使用了货仓余额
                    userProfitL1.setId(userProfitInfo.getTemps());
                    userProfitL1.setProfitMoney(canPay.subtract(truthPayMoney));
                    userProfitL1.setUpdateTime(date);


                    order.setEndMoney(BigDecimal.ZERO);
                    order.setStates(1);
                    for (UserOrderSubs subOrder : subOrders) {
                        subOrder.setRealMoney(BigDecimal.ZERO);
                        subOrder.setStates(1);
                        subOrder.setProfitMoney(subOrder.getSubEnd());
                    }

                    truthPayMoney = truthPayMoney.setScale(2, BigDecimal.ROUND_HALF_UP);
                    uof.setNeedPay(1);
                    uof.setNeedMoney(BigDecimal.ZERO);


                    StringBuilder stringBuilder = new StringBuilder(Constants.rewardOrderPrefix);
                    stringBuilder.append(order.getUserId() + "_" + seaOrIn).append(",")
                            .append(truthPayMoney).append(",")
                            .append(order.getId()).append(",")
                            .append(date.getTime()).append(",")
                            .append("profit");

//                    UserRankDetail down_profit = new UserRankDetail();
//                  延迟到支付返利后计算

                    UserGrowthDetail growInfo = new UserGrowthDetail();
                    growInfo.setCreateTime(date);
                    growInfo.setId(UUIDGenerator.generate());
                    growInfo.setGrowthValue(truthPayMoney.doubleValue());
                    growInfo.setUpMode(UpMode.SelfBuy);
                    growInfo.setOrdersId(orderId);
                    growInfo.setUserId(userId);
                    growInfo.setFromUserId(userId);
                    order.setFinishTime(date);
                    order.setProfitMoney(truthPayMoney);

                    userGrowthDetailMapper.insert(growInfo);
                    userProfitMapper.updateByIdSelective(userProfitL1);
                    order.setPayMoney(BigDecimal.ZERO);
                    order.setRealMoney(BigDecimal.ZERO);
                    // 订单倒计时,15秒后计算 等级收益
                    stringObjectRedisTemplate.opsForValue().set(stringBuilder.toString(), stringBuilder.toString(), 15, TimeUnit.SECONDS);
                    saveOrderAndSubsAndCart(order, subOrders, cartIds);
                    warehouseMapper.successWarehouseDetail(2, date, order.getId());
                    boolean NingBoNormal = subOrders.get(0).getTradeNum().equals("005");
                    if (NingBoNormal) {
                        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
                        opsForValue.set(Constants.ning_bo_normal + order.getId() + "_" + order.getId(), order.getId(), 10, TimeUnit.SECONDS);
                        // todo  更新库存表
                        stringRedisTemplate.delete(Constants.lifestyleOrderPrefix + order.getId());
                    }
                    return uof;
                }
            }
        }
        truthPayMoney = truthPayMoney.setScale(2, BigDecimal.ROUND_HALF_UP);
        uof.setNeedMoney(truthPayMoney);
        uof.setOrderMoney(truthPayMoney);
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        opsForValue.set(Constants.lifestyleOrderPrefix + orderId, orderId, 12, TimeUnit.HOURS);
        saveOrderAndSubsAndCart(order, subOrders, cartIds);
        return uof;
    }

    /**
     * 立即购买类型
     *
     * @param once
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public UserOrderFinalInfo dealWithOnce(OnceParam once) {
        String userId = once.getUserId();
        String skuId = once.getSkuId();
        String addressId = once.getAddressId();
        String prodId = once.getProdId();
        int profit = once.getUse();
        int account = once.getAccount();
        // 库存量
        long buyNum = once.getNum();
        // 海外物品 货仓
        String tradeNum = once.getTradeNum();


        WxUser wxUser = wxUserMapper.selectById(userId);
        if (wxUser == null) {
            throw new NoSuchObjectException("该用户不存在");
        }

        boolean isGod = false;
        List<String> specUsers = customerMapper.findSpecificUser();
        if (specUsers != null && specUsers.size() > 0 && specUsers.contains(userId)) {
            isGod = true;
        }

        Product product = productMapper.selectProdById(prodId);

        if (product == null || (product != null && product.getStates() == 1)) {
            throw new ParameterNullException("该商品已下架");
        }
        if (product.getIsBehalf() != null && product.getIsBehalf() == 0) {
            logger.info("代发商品无库存");
        } else {
            List<Warehouse> warehouseList = warehouseMapper.selectWarehouseInfo(skuId, tradeNum);
            if (CollectionUtils.isEmpty(warehouseList)) {
                throw new ParameterNullException("该商品不存在");
            }
            int totalStore = warehouseList.stream().mapToInt(s -> s.getNowNumber()).sum();
            if (totalStore == 0) {
                throw new NoSuchObjectException(402, "暂无库存 o(╥﹏╥)o");
            }
            Integer prodNum = warehouseList.get(0).getProdNum();
            if (prodNum != null && prodNum != 0) {
                if (totalStore < buyNum * prodNum) {
                    throw new NoSuchObjectException(402, "数量超过库存啦");
                }
            } else {
                if (totalStore < buyNum) {
                    throw new NoSuchObjectException(402, "数量超过库存啦");
                }
            }
        }

        Date date = new Date();
        String orderId = idGen.getIdDefault() + "";
        String orderCodes = UUIDGenerator.generateOrderNo("DG");
        // 子订单
        List<UserOrderSubs> subOrders = new ArrayList<>();

        HashMap<String, String[]> two = new HashMap<>();
        HashMap<String, String> three = new HashMap<>();
        HashMap<String, String> four = new HashMap<>();


        // 用户地址
        UserAddress address = userAddressMapper.selectById(addressId);
        String code = address.getCode();
        List<String> codes = Arrays.asList("540000", "650000", "710000", "810000", "820000", "900000");
        if (code != null && !codes.contains(code)) {
            code = "E";
        }
        if (code == null || "".equals(code)) {
            code = "E";
        }
        address.setCode(code);
        String realName = "";
        String idCard = "";
        String phone = "";

        // 校验订单的实名信息
        if (product.getInOrOut() == 2) {
            List<UserVerifyInfo> verifyInfos = customerMapper.selectUserVerifyInfo(userId);
            if (verifyInfos != null && verifyInfos.size() > 0) {
                realName = verifyInfos.get(0).getUsername();
                idCard = verifyInfos.get(0).getIdCard();
                phone = verifyInfos.get(0).getPhone();
            } else {
                throw new NoSuchObjectException(402, "您的实名信息与微信不一致,请核验后重试!");
            }
        }


        // 用户等级信息
        UserRankMoney userRank = userRankMapper.selectUserRankAndMoney(userId);
        if (userRank != null) {
            userRank.setTradeNum(tradeNum);
        }
        // 额外费
        List<ProductExtraInfo> extraFees = userCartMapper.selectProdExtraInfo();
        // 海外包邮
        List<FeeData> data = productMapper.selectProductFeeData2();
        int seaOrIn = 0;
        //  总订单金额
        BigDecimal totalBill = BigDecimal.ZERO;
        // 最终金额
        BigDecimal truthPayMoney = BigDecimal.ZERO;
        // 所有的关税
        BigDecimal totalGateFee = BigDecimal.ZERO;
        UserOrderSubs subOrder = orderMultiProcess(2, userId, isGod, idCard, skuId, (int) buyNum, date, orderId, orderCodes, userRank, totalBill
                , totalGateFee, extraFees, code, realName);
        totalBill = subOrder.getTempBill();
        totalGateFee = subOrder.getTempGateFee();
        BigDecimal tempDiscount = subOrder.getTempDiscount();
        subOrders.add(subOrder);

        // 订单的realMoney
        BigDecimal orderRealMoney = subOrders.stream().map(UserOrderSubs::getRealMoney).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal expressFree = subOrders.get(0).getExpressFree();
        int toUseExpress = subOrders.get(0).getToUseExpress();
        seaOrIn = subOrder.getInOrOut();
        for (UserOrderSubs sub : subOrders) {
            BigDecimal realExFee = expressFree.multiply(sub.getSubBill()).divide(totalBill, 2, BigDecimal.ROUND_HALF_UP);
            sub.setExpressFree(realExFee);
            // 需要交 运费
            if (toUseExpress == 0) {
                BigDecimal subEnd = sub.getSubEnd();
                sub.setSubEnd(subEnd.add(realExFee));
            }
            if (sub.getToUseTariff() == 0) {
                BigDecimal subEnd = sub.getSubEnd();
                sub.setSubEnd(subEnd.add(sub.getTariffFree()));
            }
        }

        truthPayMoney = subOrders.stream().map(UserOrderSubs::getSubEnd).reduce(BigDecimal.ZERO, BigDecimal::add);


        UserOrder order = new UserOrder();
        order.setCreateTime(date).setUpdateTime(date).setId(orderId);
        order.setAddressId(addressId).setUserId(userId);
        order.setDeleted(0).setStates(0).setUserDiscount(1.0);
        order.setProfitMoney(BigDecimal.ZERO).setPayMoney(BigDecimal.ZERO);
        order.setOrdersCodes(orderCodes).setPhone(phone);
        order.setBillMoney(totalBill).setEndMoney(truthPayMoney);
        order.setTariffFree(totalGateFee).setTradeType(seaOrIn);
        order.setRealMoney(orderRealMoney).setOrderDiscount(tempDiscount.doubleValue());
        order.setOrderChannel(wxUser.getIdentityType());
        order.setSendMoney(subOrder.getSendMoney());
        // 下单备注
        order.setRemark(once.getSay()).setRewardType(subOrder.getRewardType());
        order.setUsername(address.getUserName())
                .setMobile(address.getMobile())
                .setProvince(address.getProvince())
                .setCity(address.getCity())
                .setTown(address.getTown())
                .setOthers(address.getOthers());


        if (seaOrIn == 1) {
            order.setGateExpressFee(expressFree);
            order.setPushStates(-1);
        } else {
            if (seaOrIn == 0) {
                order.setPushStates(-1);
            } else {
                order.setPushStates(0);
            }
            order.setGateExpressFee(BigDecimal.ZERO);
        }
        if (tradeNum != null && !"".equals(tradeNum)) {
            order.setTradeNum(tradeNum);
        } else {
            if (seaOrIn == 0) {
                order.setTradeNum("001");
            } else if (seaOrIn == 2) {
                order.setTradeNum("002");
            }
        }
        order.setYunfei(expressFree);
        if (userRank != null) {
            order.setUserDiscount(userRank.getUserDiscount().doubleValue());
        }
        order.setProdNum((int) buyNum);
        order.setFastOrder(OrderConstants.NORMAL_ORDER);

        UserOrderFinalInfo uof = new UserOrderFinalInfo();
        uof.setOrderId(orderId).setOrderNo(order.getOrdersCodes()).setNeedMoney(truthPayMoney)
                .setOrderMoney(truthPayMoney).setNeedPay(0);
        String cre = DateTimeUtils.formatLocalDate(order.getCreateTime());
        uof.setCreateTime(cre).setChannel(wxUser.getIdentityType()).setUserId(userId);


        // todo 结账
        UserProfit userProfitL1 = new UserProfit();
        if (account == 1 && product.getInOrOut() == 0 && !isGod) {
            // 勾选余额付款
            UserProfitInfo userProfitInfo = customerMapper.selectUserProfit(userId);
            if (userProfitInfo != null) {
                BigDecimal canPay = userProfitInfo.getCanPay();
                // 充足,账户钱够用
                if (truthPayMoney.compareTo(canPay) <= 0) {
                    // 已经使用了货仓余额
                    userProfitL1.setId(userProfitInfo.getTemps());
                    userProfitL1.setProfitMoney(canPay.subtract(truthPayMoney));
                    userProfitL1.setUpdateTime(date);


                    order.setEndMoney(BigDecimal.ZERO);
                    order.setStates(1);
                    subOrder.setStates(1);


                    uof.setNeedPay(1);
                    uof.setNeedMoney(BigDecimal.ZERO);
                    uof.setOrderMoney(BigDecimal.ZERO);


                    StringBuilder stringBuilder = new StringBuilder(Constants.rewardOrderPrefix);
                    stringBuilder.append(order.getUserId() + "_" + subOrder.getInOrOut()).append(",")
                            .append(truthPayMoney).append(",")
                            .append(order.getId()).append(",")
                            .append(date.getTime()).append(",")
                            .append("profit");

//                    UserRankDetail down_repo = new UserRankDetail();
//    延迟到 结算后统一发放返利


                    UserGrowthDetail growInfo = new UserGrowthDetail();
                    growInfo.setCreateTime(date);
                    growInfo.setId(UUIDGenerator.generate());
                    growInfo.setGrowthValue(truthPayMoney.doubleValue());
                    growInfo.setUpMode(UpMode.SelfBuy);
                    growInfo.setOrdersId(orderId);
                    order.setFinishTime(date);
                    growInfo.setUserId(userId);
                    growInfo.setFromUserId(userId);
                    subOrder.setRealMoney(BigDecimal.ZERO);
                    subOrder.setProfitMoney(truthPayMoney);
                    subOrder.setPayMoney(BigDecimal.ZERO).setRealMoney(BigDecimal.ZERO);

                    order.setProfitMoney(truthPayMoney);
                    order.setPayMoney(BigDecimal.ZERO);

                    order.setRealMoney(BigDecimal.ZERO);

                    userGrowthDetailMapper.insert(growInfo);
                    userProfitMapper.updateByIdSelective(userProfitL1);

                    // 订单倒计时,15秒后计算 等级收益
                    stringObjectRedisTemplate.opsForValue().set(stringBuilder.toString(), stringBuilder.toString(), 15, TimeUnit.SECONDS);
                    saveOrderAndSubsOfOnce(order, subOrder);
                    boolean NingBoNormal = subOrder.getTradeNum().equals("005");
                    warehouseMapper.successWarehouseDetail(2, date, order.getId());
                    if (NingBoNormal) {
                        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
                        opsForValue.set(Constants.ning_bo_normal + order.getId() + "_" + order.getId(), order.getId(), 10, TimeUnit.SECONDS);
                        // todo  更新库存表
                        stringRedisTemplate.delete(Constants.lifestyleOrderPrefix + order.getId());
                    }
                    return uof;
                }
            }
        }

        truthPayMoney = truthPayMoney.setScale(2, BigDecimal.ROUND_HALF_UP);
        uof.setNeedMoney(truthPayMoney);
        uof.setOrderMoney(truthPayMoney);
        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        opsForValue.set(Constants.lifestyleOrderPrefix + orderId, orderId, 12, TimeUnit.HOURS);
        saveOrderAndSubsOfOnce(order, subOrder);
        return uof;
    }

//
//    @Transactional(rollbackFor = Exception.class)
//    public int saveOrderAndSubsAndCart(UserOrder userOrder, List<UserOrderSubs> subs, List<String> cartIds, List<Warehouse> warehouses, List<WarehouseDetail> warehouseDetails) {
//
//
//        int one = userOrderMapper.insertMainOrder(userOrder);
//        int more = customerMapper.batchInsertSubOrders(subs);
//
//        List<UserOrderSubsSelf> uoList = new ArrayList<>();
//        for (UserOrderSubs sub : subs) {
//            List<UserOrderSubsSelf> uoList1 = sub.getUoList();
//            if (uoList1 != null && uoList1.size() > 0) {
//                uoList.addAll(uoList1);
//            }
//            List<UserOrderSubsSelf> giftList = sub.getGiftList();
//            if (giftList != null && giftList.size() > 0) {
//                uoList.addAll(giftList);
//            }
//        }
//
//        if (uoList.size() > 0) {
//            userOrderMapper.batchInsertUserOrderSubsSelf(uoList);
//        }
//        customerMapper.hiddenUserCartByIds(cartIds, userOrder.getCreateTime());
//        warehouseMapper.batchUpdateWarehouse(warehouses);
//        warehouseMapper.batchInsertWarehouseDetail(warehouseDetails);
//        applicationContext.publishEvent(new PatchProdEvent(warehouses));
//        return one + more;
//    }


    @Transactional(rollbackFor = Exception.class)
    public int saveOrderAndSubsAndCart(UserOrder userOrder, List<UserOrderSubs> subs, List<String> cartIds) {


        int one = userOrderMapper.insertMainOrder(userOrder);
        int more = customerMapper.batchInsertSubOrders(subs);

        List<UserOrderSubsSelf> uoList = new ArrayList<>();
        ArrayList<Warehouse> warehouses = new ArrayList<>();
        ArrayList<WarehouseDetail> warehouseDetails = new ArrayList<>();
        for (UserOrderSubs sub : subs) {
            List<UserOrderSubsSelf> uoList1 = sub.getUoList();
            if (uoList1 != null && uoList1.size() > 0) {
                uoList.addAll(uoList1);
            }
            List<UserOrderSubsSelf> giftList = sub.getGiftList();
            if (giftList != null && giftList.size() > 0) {
                uoList.addAll(giftList);
            }

            List<Warehouse> warehouseList = sub.getWarehouseList();
            if (warehouseList != null && warehouseList.size() > 0) {
                warehouses.addAll(warehouseList);
            }
            List<WarehouseDetail> whl = sub.getWarehouseDetails();
            if (whl != null && whl.size() > 0) {
                warehouseDetails.addAll(whl);
            }


        }

        if (uoList.size() > 0) {
            userOrderMapper.batchInsertUserOrderSubsSelf(uoList);
        }
        customerMapper.hiddenUserCartByIds(cartIds, userOrder.getCreateTime());


        warehouseMapper.batchUpdateWarehouse(warehouses);
        warehouseMapper.batchInsertWarehouseDetail(warehouseDetails);
        applicationContext.publishEvent(new PatchProdEvent(warehouses));
        return one + more;
    }


    @Transactional(rollbackFor = Exception.class)
    public int saveOrderAndSubsAndCart(UserOrder userOrder, UserOrderSubs subs, List<Warehouse> warehouses, List<WarehouseDetail> warehouseDetails) {
        int one = userOrderMapper.insertMainOrder(userOrder);
        int more = userOrderMapper.insertSubOrder(subs);
        List<UserOrderSubsSelf> uoList = subs.getUoList();
        if (uoList != null && uoList.size() > 0) {
            userOrderMapper.batchInsertUserOrderSubsSelf(uoList);
        }

        List<UserOrderSubsSelf> giftList = subs.getGiftList();

        if (giftList != null && giftList.size() > 0) {
            userOrderMapper.batchInsertUserOrderSubsSelf(giftList);
        }
        warehouseMapper.batchUpdateWarehouse(warehouses);
        warehouseMapper.batchInsertWarehouseDetail(warehouseDetails);
        applicationContext.publishEvent(new PatchProdEvent(warehouses));
        return one + more;
    }


    @Transactional(rollbackFor = Exception.class)
    public int saveOrderAndSubsOfOnce(UserOrder userOrder, UserOrderSubs subs) {
        int one = userOrderMapper.insertMainOrder(userOrder);
        int more = userOrderMapper.insertSubOrder(subs);
        List<UserOrderSubsSelf> uoList = subs.getUoList();
        if (uoList != null && uoList.size() > 0) {
            userOrderMapper.batchInsertUserOrderSubsSelf(uoList);
        }

        List<UserOrderSubsSelf> giftList = subs.getGiftList();

        if (giftList != null && giftList.size() > 0) {
            userOrderMapper.batchInsertUserOrderSubsSelf(giftList);
        }
        List<Warehouse> warehouses = subs.getWarehouseList();
        List<WarehouseDetail> warehouseDetails = subs.getWarehouseDetails();
        warehouseMapper.batchUpdateWarehouse(warehouses);
        warehouseMapper.batchInsertWarehouseDetail(warehouseDetails);
        applicationContext.publishEvent(new PatchProdEvent(warehouses));
        return one + more;
    }


    /**
     * 0 查询异常
     * 1 暂无记录
     * 2 在途中
     * 3 派送中
     * 4 已签收
     * 5 用户拒签
     * 6 疑难件
     * 7 无效单
     * 8 超时单
     * 9 签收失败
     * 10 退回
     */
    public ExpressInfos findNewExpressInfo(String orderId, String subsOrderId, String expressAbbr, String subsCodes, String expressCodes) {
        ExpressInfos expressDto = userOrderMapper.selectOrderExpressInfo(subsCodes);
        if (expressDto == null || (expressDto != null && expressDto.getStates() != 4)) {
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("Authorization", "APPCODE " + appCode);
            Map<String, String> querys = new HashMap<>();
            querys.put("nu", expressCodes);
            if (expressAbbr != null) {
                querys.put("com", expressAbbr);
                if (expressAbbr.equals("shufeng")) {
                    querys.put("receiverPhone", "");
                }
            } else {
                querys.put("com", "auto");
            }
            String res = HttpClientUtil.getRequest(expressAddress, querys, headers);
            logger.info("调用第三方接口【快递查询】返回数据 {}", res);
            ExpressInfos dto = new ExpressInfos();
            dto.setId(UUIDGenerator.generate()).setSubCodes(subsCodes);
            if (res == null || (res != null && "".equals(res))) {
                dto.setCnt("");
                return dto;
            }
            JSONObject express = JSONObject.parseObject(res);
            JSONObject res_body = express.getJSONObject("showapi_res_body");
            int retCode = res_body.getIntValue("ret_code");
            if (retCode == 0) {
                int status = res_body.getIntValue("status");
                JSONArray data = res_body.getJSONArray("data");
                dto.setStates(status);
                dto.setContents(data.toJSONString());
                dto.setExpressCode(expressCodes);
//                if (status == 4) {
//                    Date date = new Date();
//                    UserOrderSubs userOrderSubs = new UserOrderSubs();
//                    userOrderSubs.setId(subsOrderId);
//                    userOrderSubs.setUpdateTime(date);
//                    userOrderSubs.setStates(3);
//                    userOrderMapper.updateSubsByIdSelective(userOrderSubs);
//                }

            } else {
                List<ExpressArrayInfo> list = new ArrayList<>();
                dto.setStates(4);
                ExpressArrayInfo expressContent = new ExpressArrayInfo();
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String data = simpleDateFormat.format(new Date());
                expressContent.setTime(data);
                expressContent.setContext("未找到物流信息");
                list.add(expressContent);
                String parseArray = JSON.toJSONString(list);
                dto.setContents(parseArray);
                dto.setExpressCode(expressCodes);
            }
            if (expressDto == null) {
                userOrderMapper.insertExpress(dto);
            } else {
                dto.setId(expressDto.getId());
                userOrderMapper.updateExpressDto(dto);
            }
            String contents = dto.getContents();
            if (StringUtils.isNotEmpty(contents)) {
                List<ExpressArrayInfo> infos = JSONArray.parseArray(contents, ExpressArrayInfo.class);
                dto.setCnt(infos);
            }
            return dto;
        }
        String contents = expressDto.getContents();
        if (StringUtils.isNotEmpty(contents)) {
            List<ExpressArrayInfo> infos = JSONArray.parseArray(contents, ExpressArrayInfo.class);
            expressDto.setCnt(infos);
        }
        return expressDto;
    }

    /**
     * @param multi        3为购物车 ,2,立即购买,1,直升
     * @param userId
     * @param isGod        是否为特权
     * @param idCard
     * @param skuId
     * @param buyCount
     * @param date
     * @param orderId
     * @param orderCodes
     * @param userRank
     * @param totalBill
     * @param totalGateFee
     * @param extraFees
     * @param addressCode
     * @return
     */
    public UserOrderSubs orderMultiProcess(int multi, String userId, boolean isGod, String idCard, String skuId, Integer buyCount, Date date, String orderId,
                                           String orderCodes
            , UserRankMoney userRank, BigDecimal totalBill, BigDecimal totalGateFee, List<ProductExtraInfo> extraFees, String addressCode, String realName) {

//        HashMap<String, String[]> two = new HashMap<>();
        HashMap<String, String> three = new HashMap<>();
        HashMap<String, String> four = new HashMap<>();
        ProdJoinAWC joinAWC = userCartMapper.selectProdCartInfos(skuId);

        if (joinAWC == null) {
            throw new ParameterNullException("您购买的物品部分已下架,下单失败!");
        }
        Integer prodStates = joinAWC.getProdStates();
        if (prodStates == 1) {
            throw new ParameterNullException("商品[ " + joinAWC.getProdName() + " ]已下架");
        }
        Integer acStates = joinAWC.getAcStates();
        if (acStates == 1) {
            throw new ParameterNullException("商品[ " + joinAWC.getProdName() + " ]已下架");
        }
        Integer minimum = joinAWC.getMinimum();

        if (buyCount < minimum) {
            throw new ParameterNullException("该商品[" + joinAWC.getProdName() + "]," + minimum + " 件起购!");
        }

        Integer maxUse = joinAWC.getMaxUse();
        if(maxUse==0){
            Integer maximum = joinAWC.getMaximum();
            if (buyCount > maximum) {
                throw new ParameterNullException("该商品[" + joinAWC.getProdName() + "],"+ "限购"+  maximum+ "件!");
            }
        }

        String prodId = joinAWC.getProdId();
        String prodName = joinAWC.getProdName();
        String prodProfiles = joinAWC.getProdProfiles();
        Integer inOrOut1 = joinAWC.getInOrOut();
        UserOrderSubs subOrder = new UserOrderSubs();
        subOrder.setInOrOut(inOrOut1);
        subOrder.setId(UUIDGenerator.generate()).setIsSuit(joinAWC.getIsSuit())
                .setProdStandards(joinAWC.getStandards())
                .setProdSelfNum(joinAWC.getSelfNum())
                .setUnitCode(joinAWC.getUnitCode())
                .setSkuId(skuId)
                .setProductPrice(joinAWC.getProdPrice())
                .setProductNum(buyCount)
                .setProductId(prodId)
                .setUserId(userId)
                .setIdCard(idCard)
                .setRealName(realName)
                .setDeleted(0).setStates(0)
                .setCreateTime(date).setUpdateTime(date)
                .setOrdersId(orderId)
                .setPayMoney(BigDecimal.ZERO)
                .setProfitMoney(BigDecimal.ZERO)
                .setIsSwitch(0)
                .setIsGift(1).setIsSuit(1)
                .setProdCurrentPrice(joinAWC.getProdPrice())
                .setYunfei(BigDecimal.ZERO).setTime2(date).setReason2("")
                .setIsPick(0).setSubEnd(BigDecimal.ZERO).setExpressNumber("")
                .setExpressCompany("").setExpressCodes("").setZipCode("")
                .setReason1("").setOldSubsCode("").setTime1(date)
                .setApplyPic("").setTariffFree(BigDecimal.ZERO).setExpressFree(BigDecimal.ZERO);
        BigDecimal billMoney = joinAWC.getProdPrice().multiply(BigDecimal.valueOf(buyCount));
        subOrder.setSubBill(billMoney).setSubEnd(billMoney).setRealMoney(billMoney);
        subOrder.setTempDiscount(BigDecimal.ONE);
        subOrder.setSendMoney(BigDecimal.ZERO);
        subOrder.setBusinessCode(joinAWC.getBusinessCode());
        subOrder.setTradeNum(userRank.getTradeNum());
        subOrder.setTotalProdNum(joinAWC.getSelfNum() * buyCount);
        if (inOrOut1 != 2) {
            subOrder.setRealName("").setIdCard("");
        }

        if (multi == 3) {
            subOrder.setSubsCodes(UUIDGenerator.generateOrderNo("PGSC"));
        } else if (multi == 2) {
            subOrder.setSubsCodes(UUIDGenerator.generateOrderNo("DGSC"));
        } else {
            List<FastProdInfo> prodInfos = productMapper.selectFastProdInfoPagedList2();
            if (prodInfos != null && prodInfos.size() > 0) {
                FastProdInfo fastProdInfo = prodInfos.stream().filter(fp -> fp.getProdId().equals(joinAWC.getProdId()) && fp.getSkuId().equals(skuId)).findAny().get();
                BigDecimal currentPrice = fastProdInfo.getCurrentPrice();
                billMoney = currentPrice.multiply(BigDecimal.valueOf(buyCount));
                subOrder.setSubEnd(billMoney).setRealMoney(billMoney);
                subOrder.setProdCurrentPrice(currentPrice);
                subOrder.setSubBill(billMoney);
            }
            subOrder.setSubsCodes(UUIDGenerator.generateOrderNo("FGSC"));
        }

        String allIds = joinAWC.getAllAttributeValuesId();
        String[] combineIds = allIds.split(",");
        List<String> allNameIds = Arrays.asList(combineIds);


        List<ProductAttributeValues> names = productMapper.selectProdNamesByAllIds(allNameIds);
        names.forEach(name -> {
            String cateImg = name.getCateImg();
            three.put(name.getId(), name.getCategoryValue());
            if (cateImg != null && cateImg != "") {
                four.put(name.getId(), name.getCateImg());
            }
        });

        // 名称
        StringBuilder sb = new StringBuilder();
        StringBuilder img = new StringBuilder();
        for (int ls = 0; ls < combineIds.length; ls++) {
            String imgUrls = four.get(combineIds[ls]);
            if (imgUrls != null) {
                if (img.length() <= 0) {
                    img.append(imgUrls);
                }
            }
            String s = three.get(combineIds[ls]);
            if (s != null) {
                if (ls != combineIds.length - 1) {
                    sb.append(s + "、");
                } else {
                    sb.append(s);
                }
            }
        }

        subOrder.setProductRemark(prodName + "|" + prodProfiles + "|" + sb.toString());
        subOrder.setProductDiscount(1.0);
        subOrder.setSpecificImg(img.toString());
        /**
         * 处理库存
         */
        List<Warehouse> warehouseList = warehouseMapper.selectWarehouseInfo(skuId, subOrder.getTradeNum());
        Integer behalf1 = joinAWC.getBehalf();
        if (behalf1 != null && behalf1 == 0) {
            warehouseList = warehouseMapper.selectWarehouseInfoBehalf(skuId, subOrder.getTradeNum());
        }
        List<WarehouseDetail> warehouseDetails = new ArrayList<>();

        /**
         * 减库存数=商品包含数 * 商品的购买数
         */
        int realCount = joinAWC.getSelfNum() * buyCount;
        for (int m = 0; m < warehouseList.size(); m++) {
            Warehouse warehouse = warehouseList.get(m);
            Integer nowNumber = warehouse.getNowNumber();
            WarehouseDetail warehouseDetail = new WarehouseDetail();
            warehouseDetail.setOrdersId(orderId).setProductId(prodId);
            warehouseDetail.setProductName(prodName).setProfiles(prodProfiles);
            warehouseDetail.setAttributeWithCategoryId(skuId).setOrderCodes(orderCodes);
            warehouseDetail.setSubsCodes(subOrder.getSubsCodes());
            warehouseDetail.setAttributeWithCategoryName(sb.toString());
            warehouseDetail.setProductMoney(joinAWC.getProdPrice());
            // 特权价
            if (isGod) {
                warehouseDetail.setProductMoney(warehouse.getNowCost());
            }
            warehouseDetail.setWarehouseBatch(warehouse.getWarehouseBatch());
            warehouseDetail.setCreateTime(date).setUpdateTime(date);
            warehouseDetail.setNowCost(warehouse.getNowCost());
            warehouseDetail.setStates(0);

            Integer behalf = behalf1;
            if (behalf != null && behalf == 0) {
                warehouse.setNowNumber(0);
                warehouseDetail.setId(UUIDGenerator.generate());
                warehouseDetail.setProductNumber(realCount);
                warehouseDetail.setWarehouseId(warehouse.getId());
                warehouseDetails.add(warehouseDetail);
                break;
            } else {
                if (nowNumber >= realCount) {
                    int st = realCount;
                    warehouse.setNowNumber(nowNumber - st);
                    warehouseDetail.setId(UUIDGenerator.generate());
                    warehouseDetail.setProductNumber(realCount);
                    warehouseDetail.setWarehouseId(warehouse.getId());
                    warehouseDetails.add(warehouseDetail);
                    break;
                } else {
                    realCount = realCount - nowNumber;
                    warehouseDetail.setProductNumber(nowNumber);
                    warehouseDetail.setId(UUIDGenerator.generate());
                    warehouseDetail.setWarehouseId(warehouse.getId());
                    warehouseDetails.add(warehouseDetail);
                    warehouse.setNowNumber(0);
                }
            }
        }
        if (behalf1 != null && behalf1 == 0) {
            subOrder.setNowCost(warehouseList.get(warehouseList.size() - 1).getNowCost());
        } else {
            subOrder.setNowCost(warehouseList.get(warehouseList.size() - 1).getNowCost());
        }
        subOrder.setWarehouseList(warehouseList);
        subOrder.setWarehouseDetails(warehouseDetails);
        if (multi != 1) {
            subOrder.setRealMoney(subOrder.getSubBill());
        }
        ProdJoinDiscount prodJoinDiscount = userCartMapper.selectProductSkuOneJoinDiscount(skuId);


        if (isGod) {

            Integer prodSelfNum = subOrder.getProdSelfNum();
            Warehouse warehouse = warehouseList.stream().min(Comparator.comparing(Warehouse::getNowCost)).get();
            BigDecimal minPrice = warehouse.getNowCost();
            BigDecimal subEnd = minPrice.multiply(BigDecimal.valueOf(buyCount)).multiply(BigDecimal.valueOf(prodSelfNum));
            subOrder.setSubBill(subEnd);
            subOrder.setRealMoney(subEnd);
            subOrder.setSubEnd(subEnd);
            subOrder.setProdCurrentPrice(minPrice.multiply(BigDecimal.valueOf(prodSelfNum)));
            subOrder.setTempDiscount(BigDecimal.ONE);

        } else {
            if (multi != 1) {
                if (userRank != null) {
                    // 用户折扣
                    BigDecimal userDiscount = userRank.getUserDiscount();
                    // 等级返利率
                    BigDecimal rankInterest = userRank.getRankInterest();
                    // 等级返利率
                    BigDecimal seaRankRate = userRank.getSeaRankRate();

                    if (userRank.getRankNum() == 0) {
                        rankInterest = seaRankRate;
                    }

                    BigDecimal subBill = subOrder.getSubBill();
                    BigDecimal m1 = subBill.multiply(userDiscount);
                    Integer inOrOut = inOrOut1;
                    if (inOrOut == 0 || inOrOut == 2) {
                        // 折后价
                        m1 = m1.multiply(rankInterest);
                        subOrder.setTempDiscount(rankInterest);
                    } else if (inOrOut == 1) {
                        // 折后价
                        m1 = m1.multiply(seaRankRate);
                        subOrder.setTempDiscount(seaRankRate);
                    }
                    subOrder.setRealMoney(m1);
                    subOrder.setSubEnd(m1);
                }
                // 商品的折扣
                if (prodJoinDiscount != null) {
                    BigDecimal discountNum = prodJoinDiscount.getDiscountNum();
                    Integer discountCate = prodJoinDiscount.getDiscountCate();
                    Integer special = prodJoinDiscount.getSpecial();
                    // todo 商品的打折种类,
                    // todo  1,固定金额
                    // todo  0,折扣率
                    if (discountNum != null) {
                        if (discountCate == 1) {
                            subOrder.setProductDiscount(-1.0);
                            subOrder.setProdCurrentPrice(discountNum);
                            subOrder.setRealMoney(discountNum.multiply(BigDecimal.valueOf(buyCount)));
                            if (userRank != null) {
                                // 用户折扣
                                BigDecimal userDiscount = userRank.getUserDiscount();
                                // 等级返利率
                                BigDecimal rankInterest = userRank.getRankInterest();
                                // 等级返利率
                                BigDecimal seaRankRate = userRank.getSeaRankRate();
                                Integer inOrOut = inOrOut1;
                                BigDecimal realMoney = subOrder.getRealMoney();
                                realMoney = realMoney.multiply(userDiscount);
                                if (inOrOut == 0 || inOrOut == 2) {
                                    // 折后价
                                    subOrder.setSubEnd(realMoney.multiply(rankInterest));
                                } else if (inOrOut == 1) {
                                    // 折后价
                                    subOrder.setSubEnd(realMoney.multiply(seaRankRate));
                                }
                                subOrder.setRealMoney(subOrder.getSubEnd());
                            }
                        } else if (discountCate == 0) {
                            subOrder.setProdCurrentPrice(joinAWC.getProdPrice().multiply(discountNum));
                            subOrder.setRealMoney(subOrder.getRealMoney().multiply(discountNum));
                        }

                        if (discountCate == 3) {
                            subOrder.setProdCurrentPrice(discountNum);
                            subOrder.setRealMoney(discountNum.multiply(BigDecimal.valueOf(buyCount)));
                            // 0--折扣1--金额
                            int rewardType = prodJoinDiscount.getRewardType();
                            BigDecimal rewardMoney = prodJoinDiscount.getRewardMoney();
                            if (rewardType == 1) {
                                BigDecimal endRewardMoney = rewardMoney.multiply(BigDecimal.valueOf(buyCount));
                                subOrder.setSendMoney(endRewardMoney);
                                subOrder.setRewardType(4);
                            } else {
                                BigDecimal endRewardMoney = subOrder.getRealMoney().multiply(rewardMoney);
                                subOrder.setSendMoney(endRewardMoney);
                                subOrder.setRewardType(3);
                            }
                            subOrder.setSubEnd(subOrder.getRealMoney());
//                            subOrder.setProdCurrentPrice(discountNum);
//                            subOrder.setRealMoney(discountNum.multiply(BigDecimal.valueOf(buyCount)));
                        } else {

                            subOrder.setSubEnd(subOrder.getRealMoney());
                            subOrder.setSendMoney(subOrder.getSubEnd());
                        }
                    }

                    if (special != null && special == 0) {
                        if (discountCate == 2) {
                            subOrder.setProdCurrentPrice(discountNum);
                            subOrder.setNotsend(true);
                            subOrder.setSubEnd(BigDecimal.valueOf(buyCount).multiply(discountNum));
                            subOrder.setSendMoney(BigDecimal.ZERO);
                            subOrder.setRewardType(1);
                            subOrder.setRealMoney(subOrder.getSubEnd());
                        }
                    }
                }
            } else {
                subOrder.setSendMoney(subOrder.getSubEnd());
            }
        }


              /*
              todo 处理套装以及赠品
             */
        Integer isSuit = joinAWC.getIsSuit();
        Integer isGift = joinAWC.getIsGift();
        if (isSuit != null && isSuit == 0) {

            List<ProductSelf> selfList = productSelfMapper.selectByProdIdHas2(prodId, 1);
            if (!CollectionUtils.isEmpty(selfList)) {
//                BigDecimal tempBill      = subOrder.getProdCurrentPrice().multiply(BigDecimal.valueOf(subOrder.getProductNum()));
                BigDecimal tempBillPrice = subOrder.getProdCurrentPrice();

//                BigDecimal tempBill      =
                BigDecimal tempBill = subOrder.getProdCurrentPrice();
//                BigDecimal tempBillPrice = subOrder.getProdCurrentPrice().multiply(BigDecimal.valueOf(subOrder.getProductNum()));


                ArrayList<UserOrderSubsSelf> selves = new ArrayList<>();
                BigDecimal pkgTotalMoney = BigDecimal.ZERO;
                int tempSelfNum = 0;
                for (ProductSelf productSelf : selfList) {
                    List<ProdJoinAttributeWithCategory> prodJoinAttributeWithCategories = productMapper.selectProdEntryInfo2(productSelf.getProductSubsId());
                    ProdJoinAttributeWithCategory prodJoinAttributeWithCategory = prodJoinAttributeWithCategories.get(0);

                    Integer isMulti = productSelf.getIsMulti();
                    if (isMulti == 0) {
                        // 多属性的物品
                        List<ProdJoinAttributeWithCategory> pjawc = productMapper.selectProdSKUEntryInfo(productSelf.getSkuId());
                        prodJoinAttributeWithCategory = pjawc.get(0);
                    }


                    UserOrderSubsSelf oss = new UserOrderSubsSelf();

                    oss.setId(UUIDGenerator.generate());
                    oss.setNeedNum(productSelf.getNeedNum());
                    oss.setOrderId(orderId);
                    oss.setOrderSubsId(subOrder.getId());
                    oss.setProductId(productSelf.getProductSubsId());
                    oss.setSkuId(prodJoinAttributeWithCategory.getAwcId());
                    oss.setProductName(prodJoinAttributeWithCategory.getProductName());
                    oss.setProductNum(prodJoinAttributeWithCategory.getProdNum());
                    oss.setProductProf(prodJoinAttributeWithCategory.getProfiles());
                    oss.setUnitCode(prodJoinAttributeWithCategory.getUnitCode());
                    oss.setProdPrice(prodJoinAttributeWithCategory.getPrice());
                    oss.setIsGift(1);

                    int nowProdNum = oss.getNeedNum() * oss.getProductNum();
                    tempSelfNum += nowProdNum;
                    List<Warehouse> swh = warehouseMapper.selectWarehouseInfoAll2(prodJoinAttributeWithCategory.getAwcId(), subOrder.getTradeNum());

                    oss.setNowCost(swh.get(swh.size() - 1).getNowCost());
                    if (isGod) {
                        BigDecimal of = BigDecimal.valueOf(oss.getProductNum());
                        oss.setProdPrice(oss.getNowCost().multiply(of));
                        oss.setCurrentPrice(oss.getProdPrice());
                    }
                    pkgTotalMoney = pkgTotalMoney.add(oss.getProdPrice().multiply(BigDecimal.valueOf(oss.getNeedNum())));
                    // 没有多属性
                    String allAttributeValuesId = prodJoinAttributeWithCategory.getAllAttributeValuesId();
                    String[] allId = allAttributeValuesId.split(",");
                    StringBuilder ssb = new StringBuilder();
                    for (int i = 0; i < allId.length; i++) {
                        ProductAttributeValues pav = productMapper.selectProductAttributeValuesById(allId[i]);
                        ssb.append(pav.getCategoryValue());
                        ssb.append(",");
                    }
                    String endAttr = ssb.substring(0, ssb.length() - 1);
                    oss.setProductAttr(endAttr);
                    selves.add(oss);
                }

                if (!isGod) {
                    BigDecimal saleRealMoney = BigDecimal.ZERO;
                    int size = selves.size();
                    int tempOne = -1;
                    for (int i = 0; i < size; i++) {
                        UserOrderSubsSelf self = selves.get(i);
                        Integer needNum = self.getNeedNum();
                        if (needNum == 1) {
                            tempOne = i;
                        }
                        BigDecimal d2 = self.getProdPrice().multiply(BigDecimal.valueOf(needNum)).multiply(tempBillPrice);
                        BigDecimal currentPrice = d2.divide(pkgTotalMoney, 1, BigDecimal.ROUND_HALF_UP);
                        self.setCurrentPrice(currentPrice.divide(BigDecimal.valueOf(needNum), 1, BigDecimal.ROUND_HALF_UP));
                        saleRealMoney = saleRealMoney.add(self.getCurrentPrice().multiply(BigDecimal.valueOf(needNum)));
                    }

                    BigDecimal endmoney = saleRealMoney;
                    if (endmoney.compareTo(tempBill) != 0) {
                        if (endmoney.compareTo(tempBill) > 0) {
                            BigDecimal tooMoney = endmoney.subtract(tempBill);
                            if (tempOne != -1) {
                                BigDecimal currentPrice = selves.get(tempOne).getCurrentPrice();
                                selves.get(tempOne).setCurrentPrice(currentPrice.subtract(tooMoney));
                            }
                        } else {
                            BigDecimal lessMoney = tempBill.subtract(endmoney);
                            if (tempOne != -1) {
                                BigDecimal currentPrice = selves.get(tempOne).getCurrentPrice();
                                selves.get(tempOne).setCurrentPrice(currentPrice.add(lessMoney));
                            }
                        }
                    }
                }
                subOrder.setTotalProdNum(subOrder.getTotalProdNum() * tempSelfNum);
                subOrder.setUoList(selves);
                subOrder.setIsSuit(0);
            }
        }

        if (isGift != null && isGift == 0) {
            List<ProductSelf> selfList = productSelfMapper.selectByProdIdHas2(prodId, 0);
            if (!CollectionUtils.isEmpty(selfList)) {
                ArrayList<UserOrderSubsSelf> selves = new ArrayList<>();
                for (ProductSelf productSelf : selfList) {
                    List<ProdJoinAttributeWithCategory> prodJoinAttributeWithCategories = productMapper.selectProdEntryInfo2(productSelf.getProductSubsId());
                    ProdJoinAttributeWithCategory prodJoinAttributeWithCategory = prodJoinAttributeWithCategories.get(0);

                    Integer isMulti = productSelf.getIsMulti();
                    if (isMulti == 0) {
                        // 多属性的物品
                        List<ProdJoinAttributeWithCategory> pjawc = productMapper.selectProdSKUEntryInfo(productSelf.getSkuId());
                        prodJoinAttributeWithCategory = pjawc.get(0);
                    }

                    UserOrderSubsSelf orderSubsSelf = new UserOrderSubsSelf();
                    orderSubsSelf.setId(UUIDGenerator.generate());
                    orderSubsSelf.setNeedNum(productSelf.getNeedNum());
                    orderSubsSelf.setOrderId(orderId);
                    orderSubsSelf.setOrderSubsId(subOrder.getId());
                    orderSubsSelf.setProductId(productSelf.getProductSubsId());
                    orderSubsSelf.setSkuId(prodJoinAttributeWithCategory.getAwcId());
                    orderSubsSelf.setProductName(prodJoinAttributeWithCategory.getProductName());
                    orderSubsSelf.setProductNum(prodJoinAttributeWithCategory.getProdNum());
                    orderSubsSelf.setProductProf(prodJoinAttributeWithCategory.getProfiles());
                    orderSubsSelf.setUnitCode(prodJoinAttributeWithCategory.getUnitCode());
                    orderSubsSelf.setProdPrice(prodJoinAttributeWithCategory.getPrice());
                    orderSubsSelf.setCurrentPrice(BigDecimal.ZERO);
                    orderSubsSelf.setIsGift(0);

                    List<Warehouse> swh = warehouseMapper.selectWarehouseInfoAll2(prodJoinAttributeWithCategory.getAwcId(), subOrder.getTradeNum());

                    orderSubsSelf.setNowCost(swh.get(swh.size() - 1).getNowCost());
                    if (isGod) {
                        orderSubsSelf.setProdPrice(orderSubsSelf.getNowCost());
                        BigDecimal of = BigDecimal.valueOf(orderSubsSelf.getProductNum());
                        orderSubsSelf.setProdPrice(orderSubsSelf.getNowCost().multiply(of));
                        orderSubsSelf.setCurrentPrice(orderSubsSelf.getProdPrice());
                    }
                    // 没有多属性
//                    ProductAttributeValues pav = productMapper.selectProductAttributeValuesById(prodJoinAttributeWithCategory.getAllAttributeValuesId());
                    String allAttributeValuesId = prodJoinAttributeWithCategory.getAllAttributeValuesId();
                    String[] allId = allAttributeValuesId.split(",");
                    StringBuilder ssb = new StringBuilder();
                    for (int i = 0; i < allId.length; i++) {
                        ProductAttributeValues pav = productMapper.selectProductAttributeValuesById(allId[i]);
                        ssb.append(pav.getCategoryValue());
                        ssb.append(",");
                    }
                    String endAttr = ssb.substring(0, ssb.length() - 1);
                    orderSubsSelf.setProductAttr(endAttr);
                    selves.add(orderSubsSelf);
                }
                subOrder.setGiftList(selves);
                subOrder.setIsGift(0);
            }
        }


        // 用户等级以及折扣
        totalBill = totalBill.add(subOrder.getSubBill());


        if (extraFees != null && extraFees.size() > 0) {
            // todo
            List<ProductExtraInfo> collect = extraFees.stream().filter(ll -> ll.getTradeType() == inOrOut1 && ll.getProvinceCode().equals(addressCode)).collect(Collectors.toList());
            if (collect != null && collect.size() > 0) {
                ProductExtraInfo otherFee = collect.get(0);
                // 使用邮费
                int toUse = otherFee.getToUse();
                // 使用关税
                int toUse2 = otherFee.getToUse2();
                // todo  关税
                double chargesNumber = otherFee.getChargesNumber();
                // todo 运费
                BigDecimal expressFee = otherFee.getChargesPrice();
                // todo 关税
                //
                BigDecimal oneMoney = subOrder.getProdCurrentPrice().multiply(BigDecimal.valueOf(subOrder.getProductNum()));
                BigDecimal rateMoney = BigDecimal.valueOf(chargesNumber).multiply(oneMoney).setScale(2, BigDecimal.ROUND_HALF_UP);
                subOrder.setExpressFree(expressFee);
                subOrder.setToUseExpress(toUse);
                subOrder.setToUseTariff(toUse2);
                if (inOrOut1 == 2) {
                    if (isSuit != null && isSuit == 0) {
                        List<UserOrderSubsSelf> uoList = subOrder.getUoList();
                        BigDecimal tempRateMoney = BigDecimal.ZERO;
                        tempRateMoney.setScale(2, BigDecimal.ROUND_HALF_UP);
                        for (UserOrderSubsSelf subsSelf : uoList) {
                            String productId = subsSelf.getProductId();
                            ProdSkuTaxReq taxReq = productMapper.selectProdTaxExtra(productId);
                            if (taxReq != null) {
                                BigDecimal prodCurrentPriceUnit = subsSelf.getCurrentPrice().divide(BigDecimal.valueOf(subsSelf.getProductNum()), 2, RoundingMode.HALF_UP);
                                BigDecimal tempMoney = taxReq.getCriticalValue();
                                String prodSpecSim = taxReq.getProdSpecSim();
                                BigDecimal decimal = BigDecimal.ONE;
                                try {
                                    if (prodSpecSim != null && !"".equals(prodSpecSim)) {
                                        decimal = new BigDecimal(taxReq.getProdSpecSim());
                                    } else {
                                        String s = productMapper.selectProdSpedUnit(subsSelf.getProductProf());
                                        if (s != null && !"".equals(s)) {
                                            decimal = new BigDecimal(s);
                                        } else {
                                            decimal = BigDecimal.ONE;
                                        }
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                    String s = productMapper.selectProdSpedUnit(subsSelf.getProductProf());
                                    if (s != null && !"".equals(s)) {
                                        decimal = new BigDecimal(s);
                                    } else {
                                        decimal = BigDecimal.ONE;
                                    }

                                }
                                prodCurrentPriceUnit = prodCurrentPriceUnit.divide(decimal, 2, BigDecimal.ROUND_HALF_UP);
                                if (tempMoney.compareTo(prodCurrentPriceUnit) <= 0) {
                                    BigDecimal subRateMoney = subsSelf.getCurrentPrice().multiply(BigDecimal.valueOf(subsSelf.getNeedNum())).multiply(taxReq.getLargeTax());
                                    subRateMoney = subRateMoney.multiply(BigDecimal.valueOf(subOrder.getProductNum()));
                                    subRateMoney.setScale(2, BigDecimal.ROUND_HALF_UP);
                                    subsSelf.setTaxFee(subRateMoney);
                                    tempRateMoney = tempRateMoney.add(subRateMoney).setScale(2, BigDecimal.ROUND_HALF_UP);
                                    logger.info("-----商品的完税价:" + subsSelf.getCurrentPrice() + "__关税:" + subRateMoney);
                                } else {
                                    BigDecimal subRateMoney = subsSelf.getCurrentPrice().multiply(BigDecimal.valueOf(subsSelf.getNeedNum())).multiply(BigDecimal.valueOf(chargesNumber));
                                    subRateMoney = subRateMoney.multiply(BigDecimal.valueOf(subOrder.getProductNum()));
                                    subRateMoney.setScale(2, BigDecimal.ROUND_HALF_UP);
                                    subsSelf.setTaxFee(subRateMoney);
                                    tempRateMoney = tempRateMoney.add(subRateMoney).setScale(2, BigDecimal.ROUND_HALF_UP);
                                    logger.info("-----商品的完税价:" + subsSelf.getCurrentPrice() + "__关税:" + subRateMoney);

                                }
                            } else {
                                BigDecimal multiply = subsSelf.getCurrentPrice().multiply(BigDecimal.valueOf(subsSelf.getNeedNum())).multiply(BigDecimal.valueOf(chargesNumber));
                                multiply = multiply.multiply(BigDecimal.valueOf(subOrder.getProductNum()));
                                multiply.setScale(2, BigDecimal.ROUND_HALF_UP);
                                subsSelf.setTaxFee(multiply);
                                tempRateMoney = tempRateMoney.add(multiply).setScale(2, BigDecimal.ROUND_HALF_UP);
                                logger.info("-----商品的完税价:" + subsSelf.getCurrentPrice() + "__关税:" + multiply);
                            }

                        }
                        rateMoney = tempRateMoney.setScale(2, BigDecimal.ROUND_HALF_UP);
                    } else {
                        ProdSkuTaxReq taxReq = productMapper.selectProdTaxExtra(subOrder.getProductId());
                        if (taxReq != null) {
                            BigDecimal prodCurrentPriceUnit = subOrder.getProdCurrentPrice().divide(BigDecimal.valueOf(subOrder.getProdSelfNum()), 2, BigDecimal.ROUND_HALF_UP);
                            BigDecimal tempMoney = taxReq.getCriticalValue();
                            String prodSpecSim = taxReq.getProdSpecSim();
                            BigDecimal decimal = BigDecimal.ONE;
                            try {
                                if (prodSpecSim != null && !"".equals(prodSpecSim)) {
                                    decimal = new BigDecimal(taxReq.getProdSpecSim());
                                } else {
                                    String s = productMapper.selectProdSpedUnit(prodProfiles);
                                    if (s != null && !"".equals(s)) {
                                        decimal = new BigDecimal(s);
                                    } else {
                                        decimal = BigDecimal.ONE;
                                    }
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                                decimal = BigDecimal.ONE;
                            }
                            prodCurrentPriceUnit = prodCurrentPriceUnit.divide(decimal, 2, BigDecimal.ROUND_HALF_UP);
                            if (tempMoney.compareTo(prodCurrentPriceUnit) <= 0) {
                                rateMoney = subOrder.getProdCurrentPrice().multiply(BigDecimal.valueOf(subOrder.getProductNum())).multiply(taxReq.getLargeTax());
                                rateMoney.setScale(2, BigDecimal.ROUND_HALF_UP);
                            } else {
                                rateMoney = subOrder.getProdCurrentPrice().multiply(BigDecimal.valueOf(subOrder.getProductNum())).multiply(BigDecimal.valueOf(chargesNumber));
                                rateMoney.setScale(2, BigDecimal.ROUND_HALF_UP);
                            }
                        }
                    }
                }
                subOrder.setTariffFree(rateMoney);
                totalGateFee = totalGateFee.add(rateMoney);
            }
        }
        subOrder.setSubBill(subOrder.getProdCurrentPrice().multiply(BigDecimal.valueOf(subOrder.getProductNum())));
        subOrder.setTempBill(totalBill).setTempGateFee(totalGateFee);
        return subOrder;
    }

    @Override
    public UserCertInfo latestUserCertInfo(String userId) {
        UserCertInfo cert = new UserCertInfo();
        cert.setIdCard(null).setUsername(null).setHas(1);
        List<UserBankCert> certs = userOrderMapper.selectUserCertOrder(userId);
        if (certs != null && certs.size() > 0) {
            Optional<UserBankCert> any = certs.stream().filter(cc -> {
                if (cc.getIdCard() != null && cc.getIdCard().length() >= 15 && cc.getUsername() != null && !"".equals(cc.getUsername())) {
                    return true;
                } else {
                    return false;
                }
            }).findAny();
            if (any.isPresent()) {
                UserBankCert userBankCert = any.get();
                String username = userBankCert.getUsername();
                String idCard = userBankCert.getIdCard();
                String phone = userOrderMapper.selectById(userBankCert.getOrderId()).getPhone();
                cert.setIdCard(idCard).setUsername(username).setPhone(phone);
                cert.setHas(0);
                return cert;
            }
        }
        return cert;
    }

}
